擴展配置節
這章內容大部分摘自 .NET之美 這本書的!
我們平常使用的appSettings及connectionStrings,在webconfig中並沒有看到configSection節點 ,那是由哪個類型處理的呢?這是因為它們的節點處理類型定義在了machine.config中
<?xml version="1.0" encoding="UTF-8"?> <configuration> <configSections> <section name="appSettings" type="System.Configuration.AppSettingsSectiSystem.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" restartOnExternalChanges="false" requirePermission="false"/> <section name="connectionStrings" type="System.Configuration.ConnectionStringsSection, System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"requirePermission="false"/> </configSections> </configuration>
可以看到,appSettings是由System.Configuration.AppSettingsSection類型處理的,connectionStrings則是由System.Configuration.ConnectionStringsSection類型處理的 ;
另外再觀察一下machine.config就會發現,處理程序分成了兩種類型:一種是以Section結尾的,比如AppSettingsSection和ConnectionStringsSection這兩個;還有一種是
Handler結尾的,比如:
<section name="system.data.dataset" type="System.Configuration.NameValueFileSectionHandler, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" restartOnExternalChanges="false"/>
可以看到type屬性System.Configuration.NameValueFileSectionHandler是以Handler結尾的。 之所以會有這樣的區別,是因為.NET中對於節點有兩種處理方式,一種是定義一個繼承自System.Configuration.ConfigurationSection的類,這也就是以Section結尾的類型;一種是實現System.Configuration.IConfigurationSectionHandler接口,也就是以Handler結尾的類型。 .NET Framework 2.0以後版本推薦采用繼承ConfigurationSection類的方式。 本章的示例大多數采用的是IConfigurationSectionHandler接口的方式,同時也會提供一個繼承
ConfigurationSection類的方式作為對比。
type由兩部分組成,由逗號“,”分隔,前半部分是類型名稱,後半部分是類型所在的程序集名稱。
一、.NET內置處理程序
.NET內置的處理程序定義於machine.config中,提供全局服務,無須進行任何額外工作就可以直接使用。 但是使用內置節點在很多情況下不一定方便,比方說,我們
希望保存站點使用的郵件服務器的地址、 用戶名和密碼,那麽以前的做法,配置文件會是類似這樣的:
<appSettings> <add key="SiteName" value="TraceFact.Net"/> <add key="Version" value="v1.0.08040301" /> <add key="GreetingLanguage" value="Chinese" /> <add key="MailServer" value="mail.tracefact.net" /> <add key="MailUser" value="jimmyzhang" /> <add key="MailPassword" value="123456"/> </appSettings>
這樣看起來比較散亂:MailServer、 MailUser、 MailPassword很明顯是一組相關的數據,但是和其他的配置混在了一起。 如果可以自定義一個節點,情況就會好很多,比如:
<?xml version="1.0"?> <configuration> <!-- 其余略 --> <mailServeraddress="mail.tracefact.net" userName="jimmyzhang" password="123456 </configuration
這樣看起來就好了很多,mailServer表示這是一個關於郵件服務器配置的節點,它的屬性/值分別代表存儲的相應值。
如果現在不做任何修改,直接運行程序,則會拋出異常“未經處理的異常:System.Configuration.ConfigurationErrorsException:配置系統未能初始化---
>System.Configuration.ConfigurationErrorsException:無法識別的配置節點mailServer。 ”。這是因為.NET底層的處理類型不認識這個節點。
為了避免發生這個錯誤,必須在configSection中指定對mailServer節點的處理程序 。有時候,我們希望繞過.NET的機制,直接使用System.Xml命名空間下的類來對配置文件(App.config
也是標準的Xml文件)進行操作,但是因為這裏會報錯,所以有的人幹脆就新建一個xml文件,然後對新建的xml文件進行操作。 實際上,可以通過指定IgnoreSectionHandler或者
IgnoreSection處理程序的方式來進行處理,如同它們的名稱所暗示的,這兩個處理程序什麽都不做,僅僅是讓.NET忽略自定義的配置節點。 修改App.config,在根節點configuration下
創建configSections節點,然後再添加一個section節點,指定它的name屬性值為mailServer,意為指定mailServer節點的處理程序,然後指定type為System.Configuration.IgnoreSection:
<?xml version="1.0"?> <configuration> <configSections> <!-- 使用IgnoreSection,可以將指定的XMl節點忽視掉 --> <section name="mailServer" type="System.Configuration.IgnoreSection,System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" allowLocation="false" restartOnExternalChanges="true" /> </configSections> <!-- 自定義節點 mailServer --> <mailServer address="mail.tracefact.net" userName="jimmyzhang" password="123456 </configuration>
此時再次運行程序,就不會再拋出異常了 ;
二、 使用自定義節點和自定義處理程序
假如站點更大一些,只使用一個郵件服務器壓力太大,需要設置多個郵件服務器,對於子域名forum.tracefact.net使用一個郵件服務器;對於blog.tracefact.net使用另一個郵件
服務器,這時應如何設置App.config呢? 此時,就會需要類似下面這樣結構的配置:
<?xml version="1.0"?><configuration> <!--使用自定義節點和自定義處理程序 --> <mailServerGroup provider="www.edong.com"> <mailServer client="forum.tracefact.net"> <address>mail1.tracefact.net</address> <userName>jimmyzhang</userName> <password>123456</password> </mailServer> <mailServer client="blog.tracefact.com"> <address>mail2.tracefact.net</address> <userName>webmaster</userName> <password>456789</password> </mailServer> </mailServerGroup> </configuration>
mailServerGroup節點包含了所有關於郵件服務器的信息。 它的provider屬性說明郵件服務器是由哪個ISP(Internet Service Provider互聯網服務供應商)提供的,這裏是中國易動
網(www.edong.com)。 其下的節點mailServer是指具體的郵件服務器,client說明此郵件服務器為哪個域名提供服務,address說明郵件服務器的地址,userName和password分別為
用戶名和密碼。
處理方式有兩種,一種是實現IConfigurationSectionHandler接口,一種是繼承ConfigurationSection類。
1.0 自定義節點處理程序—實現IConfigurationSectionHandler接口
IConfigurationSectionHandler接口的定義如下 :
// // 摘要: // 處理對特定的配置節的訪問。 public interface IConfigurationSectionHandler { // // 摘要: // 創建配置節處理程序。 // // 參數: // parent: // 父對象。 // // configContext: // 配置上下文對象。 // // section: // 節 XML 節點。 // // 返回結果: // 創建的節處理程序對象。 object Create(object parent, object configContext, XmlNode section); }
它只要求實現一個方法:Create(),當在ConfigurationManager對象上調用GetSection("sectionName")方法的時候,實際上會委托給這個Create()方法進行處理。 這個
方法最重要的一個參數是類型為XmlNode的section,它代表著名為"sectionName"的節點。它返回一個object類型的對象,這個對象通常是自定義的一個關於這個節點的配置對象,對
象的字段和屬性映射節點的屬性和文本值,用以提供強類型的訪問(也可以返回一個Hashtable,這樣就無須自定義類型)。
節點在傳遞時有一個類型轉換,在調用GetSection()時,傳遞的是String類型的節點名稱;而在Create()方法中,傳遞的是該名稱的XmlNode類型的節點。
//未完,有空再寫
擴展配置節