.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))
。
|