.Net Framework
的源码是微软编程大师们智慧的结晶,是我们开发人员梦寐以求的知识宝藏。
挖掘这座宝藏是我们快速提升自身编程思想水平的重要途径。
下面是我研究分析
.Net Framework
一部分代码后的一点心得,共享出来,希望对大家有所帮助,当然,分析不对的地方,还望指正,不胜感激。
System.Configuration.ConfigurationSettings
类
相信大家对这个类都不陌生吧。
ConfigurationSettings
类重要的方法是
(
在我下面的分析中,方法也包括属性
)
-
AppSettings
属性
用于获取
元素配置节中的配置设置。
-
GetConfig
方法
返回用户定义的配置节的配置设置。
在我们的项目开发中,我们经常通过
ConfigurationSettings.AppSettings["myKey"]
的方法
来获取
web.config
配置项上
appSettings
的配置值。调用这个
ConfigurationSettings.AppSettings["myKey"]
索引器我们就可以获取到
web.cofing
配置项
appSettings
的配置值,这太方便了。如果要我们设计一个这样的功能的时候,我们会有什么想法呢。
我的想法大概的是这样的:
1.
加载
web.config
配置文件的内容
2.
分析
web.config
配置文件配置项
appSettings
节点的内容,并加载到配置项管理类中。
3.
配置项管理类中应该有一个索引器,方便外部系统访问。
让我们来分析大师们是如何实现这个类的。看看大师级人物的代码和设计思路有何高明之处。
//ConfigurationSettings
类的定义
public
sealed
class ConfigurationSettings
{
}
C#
关键字
sealed
表明此类是不能被继承的。
//
静态构造函数
static
ConfigurationSettings()
{
_initState = InitState.NotStarted;
_initLock = new object();
}
一个类最先运行的代码段就是静态构造函数,并且对于整个程序域而言静态构造函数只运行一次。
C#
关键字
static
加上类名称的方法函数就是静态构造函数。
对于一个类来说,只能有一个静态构造函数。
静态构造函数的作用主要是初始化静态变量。
以
C#
关键字
static
约束的类方法里面的代码都只能调用
静态变量或者静态方法
,
静态属性等。
静态方法:
C#
关键字
static
约束的方法就是静态方法
(
有些教材可能会称为类方法
)
,里面的代码都只能调用
静态变量或者静态方法
,
静态属性等。
//
静态变量的定义代码
private
static
object _initLock;
C#
关键字
static
表明此变量为静态变量。
//
构造函数
private
ConfigurationSettings()
{
}
发现上面的构造函数跟我们平时所写的类的构造函数有什么不同吗?
对了,就是访问权限的约束关键字
private
,平时构造函数的约束关键字都是
public
的
那么将构造函数访问权限设置为
private
有什么目的呢?
1.
防止别人的代码通过
new
操作生成对象实例。
如:
System.Configuration.ConfigurationSettings config = new System.Configuration.ConfigurationSettings();
你会发现上面的代码编译不通过,原因就是访问了
private
的构造函数,当然编译不通过啦!
2.
保证一个类仅有一个实例。
这里就是设计模式中的
Singleton
单件模式了,设置构造函数的访问权限为
private
是实现
Singleton
模式的前提
//AppSettings
静态只读属性
public static NameValueCollection AppSettings
{
get
{
ReadOnlyNameValueCollection config = (ReadOnlyNameValueCollection) GetConfig("
appSettings
");
if (config == null)
{
config = new ReadOnlyNameValueCollection(new
CaseInsensitiveHashCodeProvider(CultureInfo.InvariantCulture), new
CaseInsensitiveComparer(CultureInfo.InvariantCulture));
config.SetReadOnly();
}
return config;
}
}
通过上面的代码我们可以知道,此属性为静态只读属性
(static
关键字,只有
get
操作,而没有
set
操作
)
因为
NameValueCollection
类定义了索引访问器,所以平时我们的代码都是这样写的
ConfigurationSettings.AppSettings["myKey"]
,对于
["myKey"]
这种使用
[]
号访问的索引器,我们下面分析
NameValueCollection
类时再说明索引器。
ReadOnlyNameValueCollection config = (ReadOnlyNameValueCollection) GetConfig("
appSettings
");
注意到参数的值是
appSettings
了吗?
是不是跟我们
web.config
里面的
appSettings
的配置节点项有关联呢?他们有什么关系吗?我们往下看。
这段代码调用了
ConfigurationSettings
类的另外一个静态方法,代码如下:
public static object GetConfig(string sectionName)
//
当然这时
sectionName
== "appSettings"
{
if ((sectionName == null) || (sectionName.Length == 0))
//
判断
string
的值是不是为
Empty
时,应该用
sectionName.Length == 0
来判断
{
return null;
}
if (_initState < InitState.Usable)
{
EnsureConfigurationSystem();
}
if (_initError != null)
{
throw _initError;
}
return _configSystem.GetConfig(sectionName);
}
代码段:
if (_initState < InitState.Usable)
{
EnsureConfigurationSystem();
}
InitState
只是一个私有的枚举类型
enum
private
enum
InitState
{
NotStarted,
Started,
Usable,
Completed
}
刚才
ConfigurationSettings
类的静态构造函数是设置
initState = InitState.NotStarted;
那么第一次运行时
,
肯定会执行
EnsureConfigurationSystem()
方法了
,
我们接着看看代码的实现
private static void EnsureConfigurationSystem()
{
lock
(_initLock)
{
if (_initState < InitState.Usable)
{
_initState = InitState.Started;
try
{
_configSystem = new DefaultConfigurationSystem();
_initState = InitState.Usable;
}
catch (Exception exception)
{
_initError = exception;
_initState = InitState.Completed;
throw;
}
}
}
}
C#
关键字
lock
加锁处理。
lock
确保当一个线程位于代码的临界区时,另一个线程不进入临界区。如果其他线程试图进入一个锁定代码,则它将在释放该对象前一直等待(块)。
MSDN
的解释:
lock
关键字可将语句块标记为临界区,方法是获取给定对象的互斥锁,执行语句,然后释放该锁。
通常,如果要保护实例变量,则
lock(this)
;如果要保护
static
变量(或者如果临界区出现在给定类的静态方法中),则
lock(typeOf (class))
。
|