【问题标题】:How to Create a Configuration Section That Contains a Collection of Collections?如何创建包含集合集合的配置节?
【发布时间】:2016-01-21 00:21:54
【问题描述】:

我需要一个类似这样的配置部分:

<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 接口的情况下实现这一点的魔法。有人知道怎么做吗?

如果myConfigmySubConfignConfigurationSectionGroupConfigurationSection,我可以。

另外,如果重要的话,这将从 web.config 中使用。

【问题讨论】:

    标签: .net configuration system.configuration


    【解决方案1】:

    在您的示例配置文件中,myConfig 将是一个继承自 ConfigurationSection 的类,具有名为 mySubConfig1mySubConfig2mySubConfig3 的三个属性。

    mySubConfig1 属性的类型(以及 2 和 3)将是继承自 ConfigurationElementCollection、实现 IEnumerable&lt;ConfigElement&gt; 并用 ConfigurationCollection 装饰的类(其中设置了“AddItemName”属性到“mySubSubConfig1”)。

    以下是我在生产部署中使用的方法的完整示例实现。请务必包含 System.Configuration 程序集。 (这有点令人困惑,因为 System.Configuration 命名空间是在其他程序集中定义的,但您必须包含 System.Configuration assembly 才能使用下面的代码。)

    以下是自定义配置类:

    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>
    

    最后,这是访问和使用配置文件的代码:

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

    Sunil Singh 在他的博客上写了一个更轻量级的替代方案:
    http://blogs.quovantis.com/net-creating-a-custom-configuration-section-that-contains-a-collection-of-collections/

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-23
      • 2012-12-01
      相关资源
      最近更新 更多