具有非 ConfigurationElement 属性的自定义配置部分

Custom config section with non-ConfigurationElement properties

我有一个工作自定义配置部分。但是,通过 ConfigurationElementCollection 获取我的数据很痛苦,但是当我尝试将我的 属性 实现为 IEnumerable 时,它​​失败并显示错误:

ConfigurationErrorsException was unhandled "Property 'contacts' is not a ConfigurationElement."

这是导致失败的代码:

[ConfigurationProperty("contacts", IsDefaultCollection = false)]
public IEnumerable<string> Contacts
{
    get { return ((ContactCollection)base["contacts"]).Cast<ContactElement>().Select(x => x.Address); }
}

但是,如果我把它改成这样:

[ConfigurationProperty("contacts", IsDefaultCollection = false)]
public ContactCollection Contacts
{
    get { return ((ContactCollection)base["contacts"]); }
}

一切正常。 This 答案听起来像是微软决定不允许的事情,所以我不能拥有 ConfigurationElement 以外的任何类型的属性。真的是这样吗?如何将我的 属性 实现为 IEnumerable<string>

以防万一,我正在尝试存储电子邮件,并且我希望每个元素都有一个元素,因为它们可能有很多,我们可能希望在future,我认为单个逗号分隔的列表可能会变得丑陋。例如,类似于:

<emergency>
    <contact address="sirdank@whosebug.com" />
    <contact address="jon.skeet@whosebug.com" />
</emergency>

<emergency>
    <contact>sirdank@whosebug.com</contact>
    <contact>jon.skeet@whosebug.com</contact>
</emergency>

谢谢!

提供两种方法有什么坏处吗?第一个满足 Microsoft 的要求,第二个满足您自己的要求。

    public IEnumerable<string> Contacts
    {
        get
        {
            return ContactCollection.Cast<ContactElement>().Select(x => x.Address);     
        }
    }

    [ConfigurationProperty("contacts", IsDefaultCollection = false)]
    public ContactCollection ContactCollection
    {
        get { return ((ContactCollection)base["contacts"]); }
    }

如果您只需要一个字符串列表,一个解决方案是声明一个以逗号分隔(或任何分隔符)的值列表,如下所示:

    [ConfigurationProperty("contacts")]
    [TypeConverter(typeof(StringSplitConverter))]
    public IEnumerable<string> Contacts
    {
        get
        {
            return (IEnumerable<string>)base["contacts"];
        }
    }

有了这个TypeConverter class:

public class StringSplitConverter : TypeConverter
{
    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
    {
        return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType);
    }

    public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
    {
        return string.Format("{0}", value).Split(',');
    }
}

您的 .config 文件将简单地声明如下:

<configuration>
  ...
  <mySection contacts="bill,joe" />
  ...
</configuration>

请注意,这不适用于集合,当您始终需要明确声明 属性 时,就像 Will 的回答一样。