代码之家  ›  专栏  ›  技术社区  ›  Joe Daley

带有“添加”元素的简单列表的自定义app.config部分

  •  83
  • Joe Daley  · 技术社区  · 15 年前

    如何创建一个自定义app.config节,它只是 add 元素?

    我发现了一些例子(例如 How to create custom config section in app.config? )对于如下所示的自定义节:

    <RegisterCompanies>
      <Companies>
        <Company name="Tata Motors" code="Tata"/>
        <Company name="Honda Motors" code="Honda"/>
      </Companies>
    </RegisterCompanies>
    

    但如何避免额外的收集元素(“公司”),使其看起来与 appSettings connectionStrings 部分?换句话说,我想:

    <registerCompanies>
      <add name="Tata Motors" code="Tata"/>
      <add name="Honda Motors" code="Honda"/>
    </registerCompanies>
    
    5 回复  |  直到 7 年前
        1
  •  107
  •   Jay Walker    11 年前

    基于op-config文件的代码的完整示例:

    <configuration>
        <configSections>
            <section name="registerCompanies" 
                     type="My.MyConfigSection, My.Assembly" />
        </configSections>
        <registerCompanies>
            <add name="Tata Motors" code="Tata"/>
            <add name="Honda Motors" code="Honda"/>
        </registerCompanies>
    </configuration>
    

    下面是实现具有折叠集合的自定义配置节的示例代码

    using System.Configuration;
    namespace My {
    public class MyConfigSection : ConfigurationSection {
        [ConfigurationProperty("", IsRequired = true, IsDefaultCollection = true)]
        public MyConfigInstanceCollection Instances {
            get { return (MyConfigInstanceCollection)this[""]; }
            set { this[""] = value; }
        }
    }
    public class MyConfigInstanceCollection : ConfigurationElementCollection {
        protected override ConfigurationElement CreateNewElement() {
            return new MyConfigInstanceElement();
        }
    
        protected override object GetElementKey(ConfigurationElement element) {
            //set to whatever Element Property you want to use for a key
            return ((MyConfigInstanceElement)element).Name;
        }
    }
    
    public class MyConfigInstanceElement : ConfigurationElement {
        //Make sure to set IsKey=true for property exposed as the GetElementKey above
        [ConfigurationProperty("name", IsKey = true, IsRequired = true)]
        public string Name {
            get { return (string) base["name"]; }
            set { base["name"] = value; }
        }
    
        [ConfigurationProperty("code", IsRequired = true)]
        public string Code {
            get { return (string) base["code"]; }
            set { base["code"] = value; }
        } } }
    

    下面是一个如何从代码访问配置信息的示例。

    var config = ConfigurationManager.GetSection("registerCompanies") 
                     as MyConfigSection;
    
    Console.WriteLine(config["Tata Motors"].Code);
    foreach (var e in config.Instances) { 
       Console.WriteLine("Name: {0}, Code: {1}", e.Name, e.Code); 
    }
    
        2
  •  25
  •   JJS Joel Coehoorn    10 年前

    不需要自定义配置节。

    App.CONFIG

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
        <configSections>
            <section name="YourAppSettings" type="System.Configuration.AppSettingsSection, System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
        </configSections>
        <!-- value attribute is optional. omit if you just want a list of 'keys' -->
        <YourAppSettings>
            <add key="one" value="1" />
            <add key="two" value="2"/>
            <add key="three" value="3"/>
            <add key="duplicate" value="aa"/>
            <add key="duplicate" value="bb"/>
        </YourAppSettings>
    </configuration>
    

    检索

    // This casts to a NameValueCollection because the section is defined as a 
    /// AppSettingsSection in the configSections.
    NameValueCollection settingCollection = 
        (NameValueCollection)ConfigurationManager.GetSection("YourAppSettings");
    
    var items = settingCollection.Count;
    Debug.Assert(items == 4); // no duplicates... the last one wins.
    Debug.Assert(settingCollection["duplicate"] == "bb");
    
    // Just keys as per original question? done... use em.
    string[] allKeys = settingCollection.AllKeys;
    
    // maybe you did want key/value pairs. This is flexible to accommodate both.
    foreach (string key in allKeys)
    {
        Console.WriteLine(key + " : " + settingCollection[key]);
    }
    
        3
  •  18
  •   Community CDub    8 年前

    基于 Jay Walker's 回答上述问题,这是一个完整的工作示例,添加了索引功能:

    <configuration>
        <configSections>
            <section name="registerCompanies" 
                     type="My.MyConfigSection, My.Assembly" />
        </configSections>
        <registerCompanies>
            <add name="Tata Motors" code="Tata"/>
            <add name="Honda Motors" code="Honda"/>
        </registerCompanies>
    </configuration>
    

    下面是实现具有折叠集合的自定义配置节的示例代码

    using System.Configuration;
    using System.Linq;
    namespace My
    {
       public class MyConfigSection : ConfigurationSection
       {
          [ConfigurationProperty("", IsRequired = true, IsDefaultCollection = true)]
          public MyConfigInstanceCollection Instances
          {
             get { return (MyConfigInstanceCollection)this[""]; }
             set { this[""] = value; }
          }
       }
       public class MyConfigInstanceCollection : ConfigurationElementCollection
       {
          protected override ConfigurationElement CreateNewElement()
          {
             return new MyConfigInstanceElement();
          }
    
          protected override object GetElementKey(ConfigurationElement element)
          {
             //set to whatever Element Property you want to use for a key
             return ((MyConfigInstanceElement)element).Name;
          }
    
          public new MyConfigInstanceElement this[string elementName]
          {
             get
             {
                return this.OfType<MyConfigInstanceElement>().FirstOrDefault(item => item.Name == elementName);
             }
          }
       }
    
       public class MyConfigInstanceElement : ConfigurationElement
       {
          //Make sure to set IsKey=true for property exposed as the GetElementKey above
          [ConfigurationProperty("name", IsKey = true, IsRequired = true)]
          public string Name
          {
             get { return (string)base["name"]; }
             set { base["name"] = value; }
          }
    
          [ConfigurationProperty("code", IsRequired = true)]
          public string Code
          {
             get { return (string)base["code"]; }
             set { base["code"] = value; }
          }
       }
    }
    

    下面是一个如何从代码访问配置信息的示例。

    MyConfigSection config = 
       ConfigurationManager.GetSection("registerCompanies") as MyConfigSection;
    
    Console.WriteLine(config.Instances["Honda Motors"].Code);
    foreach (MyConfigInstanceElement e in config.Instances)
    {
       Console.WriteLine("Name: {0}, Code: {1}", e.Name, e.Code);
    }
    
        4
  •  8
  •   Bonneech    11 年前

    根据JayWalker的回答,需要通过迭代“实例”集合来访问元素。IE.

    var config = ConfigurationManager.GetSection("registerCompanies") 
                     as MyConfigSection;
    
    foreach (MyConfigInstanceElement e in config.Instances) { 
       Console.WriteLine("Name: {0}, Code: {1}", e.Name, e.Code); 
    }
    
        5
  •  3
  •   fr0ga    7 年前

    配置中的.assembly给出了异常,因为我将项目命名为“my”而不是“my.assembly”。如果使用此示例,请小心!