Как мне сделать, чтобы мой пользовательский раздел конфигурации вел себя как коллекция?

Как мне нужно написать свой кастом ConfigurationSection так что это одновременно и обработчик раздела, и коллекция элементов конфигурации?

Обычно у вас есть один класс, который наследует от ConfigurationSection, который затем имеет свойство, которое имеет тип, который наследуется от ConfigurationElementCollection, который затем возвращает элементы коллекции типа, который наследуется от ConfigurationElement, Чтобы настроить это, вам потребуется XML, который выглядит примерно так:

<customSection>
  <collection>
    <element name="A" />
    <element name="B" />
    <element name="C" />
  </collection>
</customSection>

Я хочу вырезать <collection> узел, и просто иметь:

<customSection>
  <element name="A" />
  <element name="B" />
  <element name="C" />
<customSection>

1 ответ

Решение

Я предполагаю, что collection это свойство вашего обычая ConfigurationSection учебный класс.

Вы можете украсить это свойство следующими атрибутами:

[ConfigurationProperty("", IsDefaultCollection = true)]
[ConfigurationCollection(typeof(MyElementCollection), AddItemName = "element")]

Полная реализация для вашего примера может выглядеть так:

public class MyCustomSection : ConfigurationSection
{
    [ConfigurationProperty("", IsDefaultCollection = true)]
    [ConfigurationCollection(typeof(MyElementCollection), AddItemName = "element")]
    public MyElementCollection Elements
    {
        get { return (MyElementCollection)this[""]; }
    }
}

public class MyElementCollection : ConfigurationElementCollection, IEnumerable<MyElement>
{
    private readonly List<MyElement> elements;

    public MyElementCollection()
    {
        this.elements = new List<MyElement>();
    }

    protected override ConfigurationElement CreateNewElement()
    {
        var element = new MyElement();
        this.elements.Add(element);
        return element;
    }

    protected override object GetElementKey(ConfigurationElement element)
    {
        return ((MyElement)element).Name;
    }

    public new IEnumerator<MyElement> GetEnumerator()
    {
        return this.elements.GetEnumerator();
    }
}

public class MyElement : ConfigurationElement
{
    [ConfigurationProperty("name", IsKey = true, IsRequired = true)]
    public string Name
    {
        get { return (string)this["name"]; }
    }
}

Теперь вы можете получить доступ к настройкам следующим образом:

var config = (MyCustomSection)ConfigurationManager.GetSection("customSection");

foreach (MyElement el in config.Elements)
{
    Console.WriteLine(el.Name);
}

Это позволит следующий раздел конфигурации:

<customSection>
    <element name="A" />
    <element name="B" />
    <element name="C" />
<customSection>
Другие вопросы по тегам