2012-06-09 198 views
31

我需要配置部分是這樣的:如何創建包含集合集合的配置節?

<myConfig> 
    <mySubConfig1> 
     <mySubSubConfig1 keyAttribute="value1"> 
      <mySubSubConfig1Element keyAttribute="value1"/> 
      <mySubSubConfig1Element keyAttribute="value2"/> 
     </mySubSubConfig1> 
     <mySubSubConfig1 keyAttribute="value2"> 
      <mySubSubConfig1Element keyAttribute="value1"/> 
     </mySubSubConfig1> 
    </mySubConfig1> 
    <mySubConfig2> 
     <mySubSubConfig2 keyAttribute="value1"> 
      <mySubSubConfig2Element keyAttribute="value1"/> 
      <mySubSubConfig2Element keyAttribute="value2"/> 
     </mySubSubConfig2> 
     <mySubSubConfig2 keyAttribute="value2"> 
      <mySubSubConfig2Element keyAttribute="value1"/> 
     </mySubSubConfig2> 
    </mySubConfig2> 
    <mySubConfig3> 
     <mySubSubConfig3 keyAttribute="value1"> 
      <mySubSubConfig3Element keyAttribute="value1"/> 
      <mySubSubConfig3Element keyAttribute="value2"/> 
     </mySubSubConfig3> 
     <mySubSubConfig3 keyAttribute="value2"> 
      <mySubSubConfig3Element keyAttribute="value1"/> 
     </mySubSubConfig3> 
    </mySubConfig3> 
</myConfig> 

我還沒有找到魔法,將使用舊IConfigurationSectionHandler接口允許這種withoug。有誰知道該怎麼做?

對我來說如果myConfigmySubConfignConfigurationSectionGroupConfigurationSection

另外,如果它很重要,這將在web.config中使用。

回答

63

在您的示例配置文件,myConfig將是從ConfigurationSection繼承了與三個屬性命名爲mySubConfig1mySubConfig2mySubConfig3類。

的類型mySubConfig1屬性(以及圖2和3)將是從ConfigurationElementCollection繼承,實現IEnumerable<ConfigElement>並且與ConfigurationCollection裝飾(其中「AddItemName」屬性設置爲「mySubSubConfig1」)的類。

下面是我在生產部署中使用的一種方法的完整示例實現。一定要包括System.Configuration 程序集。 (這是一個有點混亂,因爲System.Configuration命名空間中的其他assmeblies定義,但必須包括System.Configuration 裝配使用下面的代碼。)

這裏有自定義配置類:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Configuration; 

namespace ConfigTest { 
    class CustomConfigSection : ConfigurationSection { 

     [ConfigurationProperty("ConfigElements", IsRequired = true)] 
     public ConfigElementsCollection ConfigElements { 
      get { 
       return base["ConfigElements"] as ConfigElementsCollection; 
      } 
     } 

    } 

    [ConfigurationCollection(typeof(ConfigElement), AddItemName = "ConfigElement")] 
    class ConfigElementsCollection : ConfigurationElementCollection, IEnumerable<ConfigElement> { 

     protected override ConfigurationElement CreateNewElement() { 
      return new ConfigElement(); 
     } 

     protected override object GetElementKey(ConfigurationElement element) { 
      var l_configElement = element as ConfigElement; 
      if (l_configElement != null) 
       return l_configElement.Key; 
      else 
       return null; 
     } 

     public ConfigElement this[int index] { 
      get { 
       return BaseGet(index) as ConfigElement; 
      } 
     } 

     #region IEnumerable<ConfigElement> Members 

     IEnumerator<ConfigElement> IEnumerable<ConfigElement>.GetEnumerator() { 
      return (from i in Enumerable.Range(0, this.Count) 
        select this[i]) 
        .GetEnumerator(); 
     } 

     #endregion 
    } 

    class ConfigElement : ConfigurationElement { 

     [ConfigurationProperty("key", IsKey = true, IsRequired = true)] 
     public string Key { 
      get { 
       return base["key"] as string; 
      } 
      set { 
       base["key"] = value; 
      } 
     } 

     [ConfigurationProperty("SubElements")] 
     public ConfigSubElementsCollection SubElements { 
      get { 
       return base["SubElements"] as ConfigSubElementsCollection; 
      } 
     } 

    } 

    [ConfigurationCollection(typeof(ConfigSubElement), AddItemName = "ConfigSubElement")] 
    class ConfigSubElementsCollection : ConfigurationElementCollection, IEnumerable<ConfigSubElement> { 

     protected override ConfigurationElement CreateNewElement() { 
      return new ConfigSubElement(); 
     } 

     protected override object GetElementKey(ConfigurationElement element) { 
      var l_configElement = element as ConfigSubElement; 
      if (l_configElement != null) 
       return l_configElement.Key; 
      else 
       return null; 
     } 

     public ConfigSubElement this[int index] { 
      get { 
       return BaseGet(index) as ConfigSubElement; 
      } 
     } 

     #region IEnumerable<ConfigSubElement> Members 

     IEnumerator<ConfigSubElement> IEnumerable<ConfigSubElement>.GetEnumerator() { 
      return (from i in Enumerable.Range(0, this.Count) 
        select this[i]) 
        .GetEnumerator(); 
     } 

     #endregion 
    } 

    class ConfigSubElement : ConfigurationElement { 

     [ConfigurationProperty("key", IsKey = true, IsRequired = true)] 
     public string Key { 
      get { 
       return base["key"] as string; 
      } 
      set { 
       base["key"] = value; 
      } 
     } 

    } 


} 

這裏的App.config文件:

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
    <configSections> 
    <section name="CustomConfigSection" type="ConfigTest.CustomConfigSection,ConfigTest" /> 
    </configSections> 

    <CustomConfigSection> 
    <ConfigElements> 
     <ConfigElement key="Test1"> 
     <SubElements> 
      <ConfigSubElement key="-SubTest1.1" /> 
      <ConfigSubElement key="-SubTest1.2" /> 
     </SubElements> 
     </ConfigElement> 
     <ConfigElement key="Test2"> 
     <SubElements> 
      <ConfigSubElement key="-SubTest2.1" /> 
      <ConfigSubElement key="-SubTest2.2" /> 
     </SubElements> 
     </ConfigElement> 
    </ConfigElements> 
    </CustomConfigSection> 

</configuration> 

最後,這裏是其中訪問和使用配置文件中的代碼:

http://blogs.quovantis.com/net-creating-a-custom-configuration-section-that-contains-a-collection-of-collections/

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Configuration; 

namespace ConfigTest { 
    class Program { 
     static void Main(string[] args) { 

      var l_configSettings = (CustomConfigSection) ConfigurationManager.GetSection("CustomConfigSection"); 

      foreach (var l_element in l_configSettings.ConfigElements.AsEnumerable()) { 
       Console.WriteLine(l_element.Key); 

       foreach (var l_subElement in l_element.SubElements.AsEnumerable()) { 
        Console.WriteLine(l_subElement.Key); 
       } 

      } 

      Console.WriteLine("Press any key..."); 
      Console.ReadKey(true); 

     } 
    } 
} 

一個重量更輕的替代是在自己的博客寫的蘇尼爾·辛格