Basit bir "ekle" öğeleri listesi içeren özel app.config bölümü


88

Basit bir addöğe listesi olan özel bir app.config bölümünü nasıl oluşturabilirim ?

Aşağıdaki gibi görünen özel bölümler için birkaç örnek buldum (ör . App.config'de özel yapılandırma bölümü nasıl oluşturulur? ):

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

Ancak fazladan koleksiyon öğesinden ("Şirketler") appSettingsve connectionStringsbölümleri ile aynı görünmesi için nasıl kaçınabilirim ? Başka bir deyişle, şunu isterim:

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

Yanıtlar:


114

OP yapılandırma dosyasına dayalı kodlu tam örnek:

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

Daraltılmış koleksiyonla özel bir yapılandırma bölümü uygulamak için örnek kod aşağıda verilmiştir.

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

Yapılandırma bilgilerine koddan nasıl erişileceğine dair bir örnek.

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

@Jay Walker İhtiyacınız olan öğeye nasıl erişirsiniz, yani: - config.Instances ["Tata Motors"] bunu yapmak mümkün mü?
Simon

2
İşaret etmelidir <configSection>hemen sonra olmalıdır <configuration>işe bunun için etiketinin!
Vedran Kopanja

3
Ayrıca <add gerekli olduğunu da belirtmelidir. Kendi özel <etiketinizi oluşturmak bu yanıtla işe yaramaz
Steve

8
AFAIK - bu kod "config [" Tata Motors "]", yapılandırmanın indeksleyicisi dahili olarak korunuyorsa b / c derlemeyecektir. koleksiyondaki öğeleri kendi başınıza sıralamanın bir yolunu bulmanız gerekecek.
CedricB

1
@JayWalker her şey yolunda. Bölüm türü için örneğinizdeki "My.MyConfiguration, My.Assembly" beni atıyor. Yapmaya çalıştığım şey için "MyAssembly.MyConfiguration, MyAssembly" kullanmam gerekiyordu.
Glen

38

Özel konfigürasyon bölümü gerekmez.

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>

Al

// 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
Sanırım OP'nin sorusuna kesin olarak cevap vermiyor, ancak bence bu geçerli ve çok daha basit bir çözüm. En azından bana yardımcı oldu!
styl0r

2
@ styl0r haklısın. o değil kesinlikle cevap. Çözüm anahtarım / değerim yerine öznitelik adı / kodunu kullanmanız gerekiyorsa, gerçekten özel bir bölüm kullanmanız gerekir. Ancak, yapılandırma dosyasının kontrolünün sizde olduğunu ve özel bir sınıf oluşturmaktan daha iyi yapacak işlerin olduğunu varsayıyorum.
JJS

4
Çok basit ve temiz! Herhangi bir ek özel bölüm / öğe bloatware'e gerek yok.
Ondřej

2
Dilerseniz sadece sürüm numarasını değiştirerek Version = 4.0.0.0'a da güncelleyebilirsiniz. Ek basit listelere ihtiyacınız varsa en iyi cevap budur. Aynı şey "System.Configuration.ConnectionStringsSection" için de yapılabilir, ancak kopyalar uygulama ayarlarından biraz farklı şekilde işlenir.
Sharpiro

@Sharpiro, montaj versiyonuyla ilgili sorunlar mı yaşıyordunuz? Çerçevenin daha yeni sürümleri için bile derleme bağlamanın hızda olacağını düşündüm.
JJS

22

Dayanarak Jay Walker'ın yukarıdaki cevap, bu endeksleme yapmak için yeteneği ekler tam bir çalışma örneği:

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

Daraltılmış koleksiyonla özel bir yapılandırma bölümü uygulamak için örnek kod aşağıda verilmiştir.

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

Yapılandırma bilgilerine koddan nasıl erişileceğine dair bir örnek.

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

2
Bu harika. Şimdi bir Örneği güncellemek, eklemek ve silmek için örnek koda ihtiyacımız var.
Scott Hutchinson

1
Çözümünüz için teşekkürler! Bunu MS'de kim yaptıysa ... bu gerçekten gereksiz yere karmaşıktır.
Switch386

8

Jay Walker'ın cevabına göre, öğelere erişimin "Örnekler" koleksiyonu aracılığıyla yinelenerek yapılması gerekiyor. yani.

var config = ConfigurationManager.GetSection("registerCompanies") 
                 as MyConfigSection;

foreach (MyConfigInstanceElement e in config.Instances) { 
   Console.WriteLine("Name: {0}, Code: {1}", e.Name, e.Code); 
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.