如何创建包含集合集合的配置节? [英] How to Create a Configuration Section That Contains a Collection of Collections?

查看:24
本文介绍了如何创建包含集合集合的配置节?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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 接口允许这样做的魔法.有人知道怎么做吗?

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

如果 myConfigmySubConfignConfigurationSectionGroupConfigurationSection,我就可以了.

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 将是一个继承自 ConfigurationSection 的类,具有三个名为mySubConfig1mySubConfig2mySubConfig3.

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 的类code> 并用 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 命名空间是在其他程序集中定义的,但是您必须包含 System.Configuration 程序集 才能使用下面的代码.)

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>

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

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

        }
    }
}

Sunil Singh 在他的博客上写了一个更轻量的替代方案:
http://blogs.quovantis.com/net-creating-a-custom-configuration-section-that-c​​ontains-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/

这篇关于如何创建包含集合集合的配置节?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆