2012-06-09 5 views
31

Ich brauche einen Konfigurationsabschnitt etwas wie folgt aus:Wie erstellt man einen Konfigurationsabschnitt, der eine Sammlung von Sammlungen enthält?

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

Ich habe noch nicht den Zauber gefunden, die diese withoug mit dem alten IConfigurationSectionHandler Schnittstelle erlauben würde. Weiß jemand wie es geht?

Es ist bei mir in Ordnung, wenn myConfig und die mySubConfignConfigurationSectionGroup oder ConfigurationSection sind.

Wenn dies von Bedeutung ist, wird dies von web.config verwendet.

Antwort

63

In Ihrem Beispiel Konfigurationsdatei, myConfig wäre eine Klasse sein, die von ConfigurationSection erbt mit drei Eigenschaften mySubConfig1 genannt, mySubConfig2 und mySubConfig3.

Der Typ der mySubConfig1 Eigenschaft (sowie 2 und 3) würde eine Klasse sein, die von ConfigurationElementCollection erbt, implementiert IEnumerable<ConfigElement> und ist mit ConfigurationCollection dekoriert (wo die „AddItemName“ Eigenschaft „mySubSubConfig1“ gesetzt ist).

Im Folgenden finden Sie eine vollständige Beispielimplementierung eines Ansatzes, den ich in einer Produktionsbereitstellung verwendet habe. Stellen Sie sicher, dass die System.Konfiguration Baugruppe enthalten ist. (Es ist ein wenig verwirrend, weil der System.Configuration Namespace in anderen assmeblies definiert ist, aber Sie müssen die System.Configuration Montage enthalten den Code zu verwenden.)

Hier sind die benutzerdefinierten Konfigurationsklassen:

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

    } 


} 

hier ist die Datei 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> 

Schließlich ist hier der Code, der die Konfigurationsdatei zugreift und verwendet:

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

     } 
    } 
} 

Eine leichtere Alternative von Sunil Singh in seinem Blog geschrieben wurde

Verwandte Themen