.Net中的System.Configuration命名空間為我們在web.config或者app.config中自定義配置提供了完美的支持。最近看到一些項目中還在自定義xml文件做程式的配置,所以忍不住寫一篇用系統自定義配置的隨筆了。 如果你已經對自定義配置瞭如指掌,請忽略這篇文章。 言歸正傳, ...

.Net中的System.Configuration命名空間為我們在web.config或者app.config中自定義配置提供了完美的支持。最近看到一些項目中還在自定義xml文件做程式的配置,所以忍不住寫一篇用系統自定義配置的隨筆了。
如果你已經對自定義配置瞭如指掌,請忽略這篇文章。
言歸正傳,我們先來看一個最簡單的自定義配置
<? xml version="1.0" encoding="utf-8" ?>
< configuration >
< configSections >
< section name="simple" type="ConfigExample.Configuration.SimpleSection,ConfigExample"/>
</ configSections >
< simple maxValue="20" minValue="1"></ simple >
</ configuration >
|
在配置文件中使用自定義配置,需要在configSections中添加一個section元素,並制定此section元素對應的類型和名字。然後再在configuration根節點下麵添加此自定義配置,如上例中的simple節點。simple節點只有兩個整形數的屬性maxValue和minValue。
要在程式中使用自定義配置我們還需要實現存取這個配置塊的類型,一般需要做如下三件事:
1. 定義類型從System.Configuration.ConfigurationSection繼承
2. 定義配置類的屬性,這些屬性需要用ConfigurationProperty特性修飾,並制定屬性在配置節中的名稱和其他一些限制信息
3. 通過基類的string索引器實現屬性的get ,set
非常簡單和自然,如下是上面配置類的實現:
public class SimpleSection:System.Configuration.ConfigurationSection
{
[ConfigurationProperty( "maxValue" ,IsRequired= false ,DefaultValue=Int32.MaxValue)]
public int MaxValue
{
get
{
return ( int ) base [ "maxValue" ];
}
set
{
base [ "maxValue" ] = value;
}
}
[ConfigurationProperty( "minValue" ,IsRequired= false ,DefaultValue=1)]
public int MinValue
{
get { return ( int ) base [ "minValue" ];}
set { base [ "minValue" ] = value; }
}
[ConfigurationProperty( "enabled" ,IsRequired= false ,DefaultValue= true )]
public bool Enable
{
get
{
return ( bool ) base [ "enabled" ];
}
set
{
base [ "enabled" ] = value;
}
}
}
|
這樣子一個簡單的配置類就完成了,怎麼在程式中使用這個配置呢?需要使用ConfigurationManager類(要引用System.configuration.dll這個dll只有在.Net2.0之後的版本中才有)的GetSection方法獲得配置就可以了。如下代碼:
SimpleSection simple = ConfigurationManager.GetSection( "simple" ) as SimpleSection;
Console.WriteLine( "simple minValue={0} maxValue = {1}" ,simple.MinValue,simple.MaxValue);
|
這個配置類太過簡陋了,可能有時候我們還需要更複雜的構造,比如在配置類中使用類表示一組數據,下麵我們看一個稍微複雜一點的自定義配置
<? xml version="1.0" encoding="utf-8" ?>
< configuration >
< configSections >
< section name="complex" type="ConfigExample.Configuration.ComplexSection,ConfigExample"/>
</ configSections >
< complex height="190">
< child firstName="James" lastName="Bond"/>
</ complex >
</ configuration >
|
這個配置的名字是complex,他有一個屬性height,他的節點內還有一個child元素這個元素有兩個屬性firstName和lastName;對於這個內嵌的節點該如何實現呢?首先我們需要定義一個類,要從ConfigurationElement類繼承,然後再用和SimpleSection類似的方法定義一些用ConfigurationProperty特性修飾的屬性就可以了,當然屬性值的get,set也要使用基類的索引器。如下實現:
public class ComplexSection : ConfigurationSection
{
[ConfigurationProperty( "height" , IsRequired = true )]
public int Height
{
get
{
return ( int ) base [ "height" ];
}
set
{
base [ "height" ] = value;
}
}
[ConfigurationProperty( "child" , IsDefaultCollection = false )]
public ChildSection Child
{
get
{
return (ChildSection) base [ "child" ];
}
set
{
base [ "child" ] = value;
}
}
}
public class ChildSection : ConfigurationElement
{
[ConfigurationProperty( "firstName" , IsRequired = true , IsKey = true )]
public string FirstName
{
get
{
return ( string ) base [ "firstName" ];
}
set
{
base [ "firstName" ] = value;
}
}
[ConfigurationProperty( "lastName" , IsRequired = true )]
public string LastName
{
get
{
return ( string ) base [ "lastName" ];
}
set
{
base [ "lastName" ] = value;
}
}
}
|
還有稍微再複雜一點的情況,我們可能要在配置中配置一組相同類型的節點,也就是一組節點的集合。如下麵的配置:
<? xml version="1.0" encoding="utf-8" ?>
< configuration >
< configSections >
< section name="complex" type="ConfigExample.Configuration.ComplexSection,ConfigExample"/>
</ configSections >
< complex height="190">
< child firstName="James" lastName="Bond"/>
< children >
< add firstName="Zhao" lastName="yukai"/>
< add firstName="Lee" lastName="yukai"/>
< remove firstName="Zhao"/>
</ children >
</ complex >
</ configuration >
|
請看children節點,它就是一個集合類,在它裡面定義了一組add元素,也可以有remove節點把已經添進去的配置去掉。
要使用自定義節點集合需要從ConfigurationElementCollection類繼承一個自定義類,然後要實現此類GetElementKey(ConfigurationElement element)和ConfigurationElement CreateNewElement()兩個方法;為了方便的訪問子節點可以在這個類裡面定義只讀的索引器。請看下麵的實現
public class Children : ConfigurationElementCollection
{
protected override object GetElementKey(ConfigurationElement element)
{
return ((ChildSection)element).FirstName;
}
protected override ConfigurationElement CreateNewElement()
{
return new ChildSection();
}
public ChildSection this [ int i]
{
get
{
return (ChildSection) base .BaseGet(i);
}
}
public ChildSection this [ string key]
{
get
{
return (ChildSection) base .BaseGet(key);
}
}
}
|
當然要使用此集合類我們必須在Complex類中添加一個此集合類的屬性,並要指定集合類的元素類型等屬性,如下:
[ConfigurationProperty( "children" , IsDefaultCollection = false )]
[ConfigurationCollection( typeof (ChildSection), CollectionType = ConfigurationElementCollectionType.AddRemoveClearMap, RemoveItemName = "remove" )]
public Children Children
{
get
{
return (Children) base [ "children" ];
}
set
{
base [ "children" ] = value;
}
}
|
我們會經常用到類似appSettings配置節的鍵值對的構造,這時候我們就不必再自己實現了,我們可以直接使用現有的System.Configuration.NameValueConfigurationCollection類來定義一個自定義的鍵值對。可以在Complex類中定義如下屬性
[ConfigurationProperty( "NVs" , IsDefaultCollection = false )]
public System.Configuration.NameValueConfigurationCollection NVs
{
get
{
return (NameValueConfigurationCollection) base [ "NVs" ];
}
set
{
base [ "NVs" ] = value;
}
}
|
然後在配置文件的complex節中添加鍵值對配置
< NVs >
< add name="abc" value="123"/>
< add name="abcd" value="12d3"/>
</ NVs >
|
到這兒已經基本上可以滿足所有的配置需求了。不過還有一點更大但是不複雜的概念,就是sectionGroup。我們可以自定義SectionGroup,然後在sectionGroup中配置多個section;分組對於大的應用程式是很有意義的。
如下配置,配置了一個包含simple和一個complex兩個section的sectionGroup
<? xml version="1.0" encoding="utf-8" ?>
< configuration >
< configSections >
< sectionGroup type="ConfigExample.Configuration.SampleSectionGroup,ConfigExample" name="sampleGroup">
< section type="ConfigExample.Configuration.SimpleSection,ConfigExample" allowDefinition="Everywhere" name="simple" />
< section type="ConfigExample.Configuration.ComplexSection,ConfigExample" allowDefinition="Everywhere" name="complex"/>
</ sectionGroup >
</ configSections >
< sampleGroup >
< simple maxValue="20" minValue="1">
</ simple >
< complex height="190">
< child firstName="James" lastName="Bond"/>
< children >
< add firstName="Zhao" lastName="yukai"/>
< add firstName="Lee" lastName="yukai"/>
< remove firstName="Zhao"/>
</ children >
< NVs >
< add name="abc" value="123"/>
< add name="abcd" value="12d3"/>
</ NVs >
</ complex >
</ sampleGroup >
</ configuration >
|
為了方便的存取sectionGroup中的section我們可以實現一個繼承自System.Configuration.ConfigurationSectionGroup類的自定義類。實現很簡單,就是通過基類的Sections[“sectionName”]索引器返回Section。如下:
public class SampleSectionGroup : System.Configuration.ConfigurationSectionGroup
{
public SimpleSection Simple
{
get
{
return (SimpleSection) base .Sections[ "simple" ];
}
}
public ComplexSection Complex
{
get
{
return (ComplexSection) base .Sections[ "complex" ];
}
}
}
|
需要註意的是SectionGroup不能使用ConfigurationManager.GetSection(string)方法來獲得,要獲得sectionGroup必須通過Configuration類的SectionGroups[string]索引器獲得,如下示例代碼:
SampleSectionGroup sample = (SampleSectionGroup)ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None).SectionGroups[ "sampleGroup" ];
|
總結:
.Net framework給我們提供了一套很方便的配置庫,我們只需要繼承對應的類簡單的配置一下就可以方便的使用在web.config或者app.config中配置的自定義節點了。
轉自 http://www.cnblogs.com/yukaizhao/archive/2011/12/02/net-web-config-costom-config-implement.html