ConfigurationElementCollection具有许多不同类型的ConfigurationElements

aba*_*hev 10 .net c# app-config system.configuration custom-configuration

是否可以使CollectionElementCollection具有许多不同类型的CollectionElements,例如:

<collection>
    <add type="MyType1, MyLib" Type1SpecificProp="1" />
    <add type="MyType2, MyLib" Type2SpecificProp="2" />
</collection
Run Code Online (Sandbox Code Playgroud)

我有这样的解决方案所需的所有类:

class MyCollection : ConfigurationElementCollection { }
class MyElement : ConfigurationElement { }
class MyType1 : MyElement { }
class MyType2 : MyElement { }
...
etc
Run Code Online (Sandbox Code Playgroud)

但是当我启动我的应用程序时,我会得到下一个可预测的错误:

无法识别的属性'Type1SpecificProp'.

因为Type1SpecificProp定义在MyType1没有MyElement,尤其是如果MyCollection有下一个方法:

protected override ConfigurationElement CreateNewElement()
{
    return new MyElement(); // but I want instantiate not the base class but by a type given
}
Run Code Online (Sandbox Code Playgroud)

即返回基类因此OnDeserializeUnrecognizedAttribute()在子类中从未被调用过.

所以问题是:如何让孩子们的班级通过自己解决未知元素?

use*_*858 11

我也研究过这个.PolymorphicConfigurationElementCollection<T> 似乎已被弃用.编辑:不是,请参阅下面的'abatishchev'的评论,我只是链接旧版本.

Rest Wing的解决方案很有希望,但不幸的是需要调用驻留在另一个命名空间中的内部方法.虽然这可以通过反射来实现,但在这种情况下它不会收到编码美的价格.

我也用Reflection挖掘了源代码并提出了以下解决方案:

[ConfigurationCollection(typeof(ElementBaseConfig), CollectionType=ConfigurationElementCollectionType.BasicMap)]
public class MyTypesConfigCollection : ConfigurationElementCollection
{
    protected override ConfigurationElement CreateNewElement()
    {
        // Not used but function must be defined
        return null;
    }

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

    protected override ConfigurationElement CreateNewElement(string elementName)
    {
        switch (elementName)
        {
            case "mytype1":
                return new MyType1Config();

            case "mytype2":
                return new MyType2Config();

            default:
                throw new ConfigurationErrorsException(
                    string.Format("Unrecognized element '{0}'.", elementName));
        }
    }

    protected override bool IsElementName(string elementName)
    {
        // Required to be true
        return true;
    }

    public override ConfigurationElementCollectionType CollectionType
    {
        get { return ConfigurationElementCollectionType.BasicMap; }
    }
}
Run Code Online (Sandbox Code Playgroud)

CollectionType的覆盖是必需的,即使已通过顶部的属性指定了它.当没有重写时,基类'CollectionType仍然引用'AddRemoveClearMap',它不会触发所需的'CreateNewElement(string elementName)'函数,但它是无参数变体'CreateNemElement()'.出于同样的原因,覆盖的IsElementName函数应该返回true.

请注意,我创建了一个ElementBaseConfig,它是MyType1Config和MyType2Config的基类,您可以在其中定义一些共享属性.

  • 你已经链接了ver.3.1,[这里是最近的](http://msdn.microsoft.com/en-us/library/bb750549%28PandP.50%29.aspx)并没有过时 (2认同)

aba*_*hev 2

Microsoft.Practices.EnterpriseLibrary.Common.Configuration.PolymorphicConfigurationElementCollection<T>来自 EntLib5 的这项工作是一种魅力。