自定义app.config部分有一个简单的“添加”元素列表
我如何创build一个自定义的app.config部分,只是一个简单的add
元素列表?
我已经find了几个例子(例如, 如何在app.config中创build自定义configuration部分? )的自定义部分,看起来像这样:
<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>
基于OPconfiguration文件的完整代码示例:
<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>
下面是示例代码来实现具有折叠收集的自定义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; } } } }
以下是如何从代码访问configuration信息的示例。
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); }
没有自定义configuration部分必要。
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]); }
根据Jay Walker的回答,这是一个完整的工作示例,增加了build立索引的function:
<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>
下面是示例代码来实现具有折叠收集的自定义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; } } } }
以下是如何从代码访问configuration信息的示例。
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); }
根据Jay Walker的回答,访问元素需要迭代“Instances”集合来完成。 即。
var config = ConfigurationManager.GetSection("registerCompanies") as MyConfigSection; foreach (MyConfigInstanceElement e in config.Instances) { Console.WriteLine("Name: {0}, Code: {1}", e.Name, e.Code); }
在configurationMy.Assembly给了我例外,因为我命名项目“我的”而不是“My.Assembly”。 要小心,如果你使用这个例子!