2010-04-27 57 views
74

如何創建僅包含add元素的簡單列表的自定義app.config部分?帶有「添加」元素的簡單列表的自定義app.config部分

我已經找到了定製部分看起來像這樣的一些例子(如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> 

但是我怎麼避免額外的集合元素(「公司」),使得它的外觀與appSettingsconnectionStrings部分相同?換句話說,我想:

<registerCompanies> 
    <add name="Tata Motors" code="Tata"/> 
    <add name="Honda Motors" code="Honda"/> 
</registerCompanies> 
+0

請將您的問題重新標記爲c#3.0而不是c#3.5 請參閱此處:http://stackoverflow.com/questions/247621/what-are-the-correct-version-numbers-for-c – Viper 2010-04-29 13:27:41

+0

嘿,好點。 – 2010-04-30 00:03:35

+0

另請參閱http://stackoverflow.com/questions/1779117/how-to-get-a-liststring-collection-of-values-from-app-config-in-wpf – 2011-09-06 15:24:24

回答

95
基於OP配置文件中的代碼

完整的示例:

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

@Jay Walker你如何去訪問您需要的項目,即: - config.Instances [「Tata Motors」]是否可以這樣做? – Simon 2014-05-27 12:50:10

+0

@Simon,查看例子用法的答案更新。 – 2014-05-30 03:52:14

+0

應該指出''應該在''標籤之後正確工作! – 2014-12-25 23:01:35

7

根據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); 
} 
12

基於以上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); 
} 
19

無需自定義配置部分。

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]); 
} 
+1

Downvotes沒有評論。痘痘在你身上... – JJS 2016-06-10 07:02:20

+0

我想這不是嚴格回答OP的問題,但我認爲這是一個有效的解決方案,而且更簡單。至少它幫助了我! – styl0r 2016-07-12 18:10:15

+1

@ styl0r你是對的。它不*嚴格*回答它。如果您必須使用屬性名稱/代碼而不是我的解決方案鍵/值,則必須使用真正的自定義部分。不過,我假設你在控制配置文件,並且比做一個自定義類有更好的事情要做。 – JJS 2016-07-13 16:02:09

2

My.Assembly在配置給了我的異常,因爲我的項目命名爲 「我」 而不是 「My.Assembly」。要小心,如果你使用這個例子!

相關問題