如何使我的自定义配置部分表现得像一个集合?

16

我应该如何编写自定义的 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>

请问您能否考虑更改问题标题以使其更具体?我建议使用类似“如何使我的自定义配置部分表现为集合?”之类的标题。这将自动从问题标题中删除不必要的“C#”,因为您已经在问题标签中打了它。 - julealgon
当你提出实际问题时,很快就会意识到有可能已经有人问过了。例如,这个可能是你问题的重复。 - julealgon
1个回答

24

我假设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>

你的示例中有三个类。我知道这是微软向我们展示如何做的方式...但这意味着你的XML将有三个级别:部分、集合、集合中的元素。我想用两个级别来完成:部分和部分中的元素(就像部分也是一个集合)。 - theBoringCoder
3
你确实仍然有三个级别的课程,但是这个例子恰好使用了你想要的例子。MyElementCollection类不会转换为XML元素。 - Elian Ebbing
3
哇,这个回复有些晚了 :) - Elian Ebbing

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接