在.Net應用程式中,我們經常看到VS為我們產生的項目工程中都會含有App.config或者Web.config這樣的檔案。這個檔案就是我們所說的應用程式設定檔。在這個檔案裡面記述著一些與我們的應用程式相關的資訊,如:資料庫連接,認證模式等。我們在程式中可以利用ConfigurationManager的ConnectionStrings屬性方便的擷取設定檔中的資料庫連接字串資訊。
可是有時候,我們需要對它進行一些擴充,加入一些自訂的元素,而不是僅僅使用預設的配置。例如,我們可能需要在程式啟動時,動態載入某個類,並對其進行初始化,而這個類或者初始化資料是我們在程式設計的時候所不知道的。相信大家都碰到過這樣的問題,這裡就不做過多的解釋了。最好的辦法無非就是把這些可能會改變的東西寫進設定檔裡面,到你能夠確定的時候,你只需要修改設定檔就Ok了,而不是產品馬上上線的時候還用30秒鐘開啟VS去改代碼。
添加一些自訂的元素到設定檔中是很容易的,只需要兩步就能搞定:
1. 在<configSections>節點中註冊你所要定義的節點名稱及用於處理該節點的配置節處理常式。代碼如下:
1 <configSections>
2 <section name="dbFactory" type="DbFactory.Configuration.DbFactorySection,DbFactory.Configuration"/>
3 </configSections>
2. 在適當的位置添加自訂的節點。代碼如下:
1 <configSections>
2 <section name="dbFactory" type="DbFactory.Configuration.DbFactorySection,DbFactory.Configuration"/>
3 </configSections>
4 <dbFactory >
5 <default factory="sql"></default>
6 <factorys>
7 <add name="sql" assembly="Hello.Data" class="SqlDbFactory" />
8 <add name="oracle" assembly="Hello.Data" class="OracleDbFactory" />
9 </factorys>
10 </dbFactory>
自訂節點算是添加完了,可是我們怎麼在程式裡面擷取這些配置資訊呢?相信大家很多都是玩XML的高手,用System.Xml下的一些類寫個XML的解析類,把我們自訂的節點資訊解析出來,不就得到我們想要的東西了嗎?的確是這樣,大牛果然是大牛,小弟實在是佩服。可是如果用這種方式來實現的話,小弟就實在沒有必要寫這篇博文了。
.Net架構為我們實現了很多的配置API,來簡化我們對設定檔的操作。在第一個步驟中,我們提到了配置節處理常式,這個程式就是用來讀寫我們自訂的節點資訊的。那麼我們又如何來實現一個配置節處理常式呢?首先我們來瞭解一下相關的類和概念。
ConfigurationSection:自訂節點都要繼承該類,以提供對自訂配置節的自訂處理和編程訪問。
ConfigurationElement:它表示設定檔內的一個元素。
ConfigurationElementCollection:它表示包含一個子項目集合的配置元素。
有了這些類,我們可以歸納起來設定檔中有兩種類型的配置元素。
第一,單一型配置元素,即繼承於ConfigurationElement的元素,它不包含任何子項目。
第二,集合型配置元素,即繼承於ConfigurationElementCollection德元素,它包含一個子項目集合。
概念往往都比較抽象,要搞清楚這些東西,我們還是結合我們上面給的例子來具體說明一下。
在<dbFactory> 配置節中有兩個元素,即<default>和<factorys>,而<factorys>元素又包含了兩個子項目。那麼在這裡<default>就是單一型配置元素,而<factorys>就是集合型配置元素。我們需要分別實現與這些元素相對應的類及其屬性。
<default>元素:它是一個單一型的元素,所以我們繼承ConfigurationElement。該元素中有一個factory屬性,那麼我們在類中進行相應的定義。代碼如下:
代碼
public class DefaultElement: ConfigurationElement
{
[ConfigurationProperty("factory")]
public string Factory
{
get
{
return this["factory"] as string;
}
set
{
this["factory"] = value;
}
}
}
注意:在屬性定義上面我們需要註冊該屬性的ConfigurationProperty特性。
<factorys>子項目:
代碼
public class FactoryElement : ConfigurationElement
{
[ConfigurationProperty( "name" )]
public string Name
{
get
{
return this["name"] as string;
}
set
{
this["name"] = value;
}
}
[ConfigurationProperty("assembly")]
public string Assembly
{
get
{
return this["assembly"] as string;
}
set
{
this["assembly"] = value;
}
}
[ConfigurationProperty("class")]
public string Class
{
get
{
return this["class"] as string;
}
set
{
this["class"] = value;
}
}
}
<factorys>元素是集合型元素,繼承ConfigurationElementCollection。
代碼
public class FactoryElements : ConfigurationElementCollection
{
protected override ConfigurationElement CreateNewElement()
{
return new FactoryElement();
}
protected override object GetElementKey( ConfigurationElement element )
{
return ((FactoryElement)element).Name;
}
public FactoryElement this[string name]
{
get
{
return BaseGet( name ) as FactoryElement;
}
}
}
ConfigurationElementCollection類是個抽象類別,你應該顯示的實現它的CreateNewElement方法和GetElementKey方法。
<dbFactory>節點,繼承於ConfigurationSection
代碼
public class DbFactorySection : ConfigurationSection
{
[ConfigurationProperty("default")]
public DefaultElement DefaultFactory
{
get
{
return this["default"] as DefaultElement;
}
set
{
this["default"] = value;
}
}
[ConfigurationProperty( "factorys" )]
public FactoryElements Factorys
{
get
{
return this["factorys"] as FactoryElements;
}
set
{
this["factorys"] = value;
}
}
}
配置節處理常式終於寫完了,把這四個類放在同一個工程目錄下,編譯成一個DLL。在你需要擷取配置資訊的地方,引用這個DLL,用DbFactorySection section = ConfigurationManager.GetSection( "dbFactory" ) as DbFactorySection;試試,section是不是你想要的東西呢?