如何创建一个配置节,其中包含的集合集合?创建一个、其中包含

2023-09-02 11:56:16 作者:朕好萌i

我需要配置部分是这样的:

I need a configuration section something like this:

<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。有谁知道该怎么办呢?

I haven't yet found the magic that would permit this withoug using the old IConfigurationSectionHandler interface. Does anyone know how to do it?

这是确定我是否 myConfig mySubConfign ConfigurationSectionGroup 配置节

It's ok with me if myConfig and the mySubConfign are ConfigurationSectionGroup or ConfigurationSection.

此外,如果它的问题,这将被用于从web.config中

Also, if it matters, this will be used from web.config.

推荐答案

在您的示例配置文件, myConfig 将是一个类继承自配置节名为三个属性 mySubConfig1 mySubConfig2 mySubConfig3

In your example config file, myConfig would be a class that inherits from ConfigurationSection with three properties named mySubConfig1, mySubConfig2 and mySubConfig3.

mySubConfig1 属性的类型(以及2和3)将是一个类继承自 ConfigurationElementCollection ,实施的IEnumerable&LT; ConfigElement&GT; 并装饰有 ConfigurationCollection (这里的AddItemName属性设置为mySubSubConfig1 )。

The type of the mySubConfig1 property (as well as 2 and 3) would be a class that inherits from ConfigurationElementCollection, implements IEnumerable<ConfigElement> and is decorated with ConfigurationCollection (where the "AddItemName" property is set to "mySubSubConfig1").

下面是我用在生产部署的方法的完整样本实现。一定要包括System.Configuration的的组装的。 (这是一个有点混乱,因为System.Configuration命名空间是其他assmeblies定义,但必须包括System.Configuration的组装的使用低于code)

Below is a complete sample implementation of an approach I used in a production deployment. Be sure to include the System.Configuration assembly. (It's a bit confusing because the System.Configuration namespace is defined in other assmeblies, but you must include the System.Configuration assembly to use the code below.)

下面是自定义配置类:

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文件:

Here's the App.config file:

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

最后,这里的code的访问和使用的配置文件:

Finally, here's the code which accesses and uses the config file:

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

        }
    }
}

一个重量更轻的替代方案是由苏尼尔·辛格在他的博客: http://blogs.quovantis.com/net-creating-a-custom-configuration-section-that-contains-a-collection-of-collections/

A lighter-weight alternative was written by Sunil Singh on his blog: http://blogs.quovantis.com/net-creating-a-custom-configuration-section-that-contains-a-collection-of-collections/