2012-06-09 39 views
31

Tôi cần một cái gì đó phần cấu hình như thế này:Làm thế nào để tạo một phần cấu hình có chứa một bộ sưu tập các bộ sưu tập?

<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> 

Tôi vẫn chưa tìm thấy sự kỳ diệu mà sẽ cho phép withoug này sử dụng giao diện cũ IConfigurationSectionHandler. Có ai biết làm thế nào để làm điều đó?

Sẽ ổn với tôi nếu myConfigmySubConfignConfigurationSectionGroup hoặc ConfigurationSection.

Ngoài ra, nếu nó quan trọng, điều này sẽ được sử dụng từ web.config.

Trả lời

63

Trong tập tin cấu hình ví dụ của bạn, myConfig sẽ là một lớp kế thừa từ ConfigurationSection với ba thuộc tính tên mySubConfig1, mySubConfig2mySubConfig3.

Các loại mySubConfig1 tài sản (cũng như 2 và 3) sẽ là một lớp kế thừa từ ConfigurationElementCollection, thực hiện IEnumerable<ConfigElement> và được trang trí với ConfigurationCollection (nơi "AddItemName" bất động sản được thiết lập để "mySubSubConfig1").

Dưới đây là một ví dụ mẫu hoàn chỉnh về cách tiếp cận mà tôi đã sử dụng trong triển khai sản xuất. Hãy chắc chắn bao gồm cấu hình System.Configuration . (Đó là một chút bối rối vì không gian tên System.Configuration được định nghĩa trong assmeblies khác, nhưng bạn phải bao gồm System.Configuration lắp ráp sử dụng mã dưới đây.)

Dưới đây là các lớp cấu hình tùy chỉnh:

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; 
      } 
     } 

    } 


} 

đây là 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> 

Cuối cùng, đây là đoạn code mà truy cập và sử dụng các tập tin cấu hình:

012.
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); 

     } 
    } 
} 

Một thay thế trọng lượng nhẹ hơn đã được viết bởi Sunil Singh trên blog của mình:
http://blogs.quovantis.com/net-creating-a-custom-configuration-section-that-contains-a-collection-of-collections/

Các vấn đề liên quan