1. 程式人生 > >擴展配置節

擴展配置節

機制 必須 區別 無法 2.0 報錯 ror 添加 摘要

這章內容大部分摘自 .NET之美 這本書的!

我們平常使用的appSettingsconnectionStrings,在webconfig中並沒有看到configSection節點 ,那是由哪個類型處理的呢?這是因為它們的節點處理類型定義在了machine.config

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<configSections>
<section name="appSettings" type="System.Configuration.AppSettingsSecti
System.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結尾的,比如AppSettingsSectionConnectionStringsSection這兩個;還有一種是

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>

這樣看起來比較散亂:MailServerMailUserMailPassword很明顯是一組相關的數據,但是和其他的配置混在了一起。 如果可以自定義一個節點,情況就會好很多,比如:

<?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節點的處理程序,然後指定typeSystem.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屬性說明郵件服務器是由哪個ISPInternet Service Provider互聯網服務供應商)提供的,這裏是中國易動
網(www.edong.com)。 其下的節點mailServer是指具體的郵件服務器,client說明此郵件服務器為哪個域名提供服務,address說明郵件服務器的地址,userNamepassword分別為
用戶名和密碼。

處理方式有兩種,一種是實現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()方法進行處理。 這個
方法最重要的一個參數是類型為XmlNodesection,它代表著名為"sectionName"的節點。它返回一個object類型的對象,這個對象通常是自定義的一個關於這個節點的配置對象,對
象的字段和屬性映射節點的屬性和文本值,用以提供強類型的訪問(也可以返回一個Hashtable,這樣就無須自定義類型)。

節點在傳遞時有一個類型轉換,在調用GetSection()時,傳遞的是String類型的節點名稱;而在Create()方法中,傳遞的是該名稱的XmlNode類型的節點。

//未完,有空再寫







擴展配置節