简体   繁体   English

MEF,我可以导出/导入具有多个MetaDataAttribute装饰的类吗?

[英]MEF, can I export/import classes with multiple MetaDataAttribute decorations?

How can I make the following code work? 如何使以下代码起作用? It throws an error saying that there are two meta data attributes of identical names, though I do not see why. 抛出一个错误,说有两个具有相同名称的元数据属性,尽管我不明白为什么。

The error message is as follows: 错误消息如下:

An unhandled exception of type 'System.InvalidOperationException' occurred in System.ComponentModel.Composition.dll System.ComponentModel.Composition.dll中发生了类型为'System.InvalidOperationException'的未处理异常

Additional information: Member or Type 'ConsoleApplication2.DoSomeMagic' contains multiple metadata entries with the name 'PluginName'. 附加信息:成员或类型'ConsoleApplication2.DoSomeMagic'包含多个名为'PluginName'的元数据条目。 The metadata entries could be coming from the ExportMetadataAttribute or from a property of a custom metadata attribute. 元数据条目可以来自ExportMetadataAttribute或来自自定义元数据属性的属性。 Either remove the duplicate entries or enable the metadata entry with name 'PluginName' to allow multiple entries via the IsMultiple property on ExportMetadataAttribute or AttributeUsage.AllowMultiple on custom metadata attributes. 删除重复的条目,或者启用名称为“ PluginName”的元数据条目,以允许通过ExportMetadataAttribute上的IsMultiple属性或自定义元数据属性上的AttributeUsage.AllowMultiple允许多个条目。

class Program
{
    static void Main(string[] args)
    {
        var program = new Program();
        program.Test();
    }

    private void Test()
    {
        //Export
        var catalog = new AssemblyCatalog(this.GetType().Assembly);
        var container = new CompositionContainer(catalog);
        container.ComposeParts(this);

        //Import Meta Data
        var import1 = container.GetExports<IMagic1, IPluginAttributeView>().Select(e => new PluginAttribute(e.Metadata));

    }
}

public interface IPluginAttributeView
{
    string PluginName { get; set; }
    string PluginConfigurationName { get; set; }
    string PluginCategory { get; set; }
    Type PluginType { get; set; }
}

[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class PluginAttribute1 : ExportAttribute, IPluginAttributeView
{
    public string PluginName { get; set; }
    public string PluginConfigurationName { get; set; }
    public string PluginCategory { get; set; }
    public Type PluginType { get; set; }

    public PluginAttribute1(string pluginName, string pluginConfigurationName, string pluginCategory, Type pluginType)
        : base(pluginType)
    {
        PluginName = pluginName;
        PluginConfigurationName = pluginConfigurationName;
        PluginCategory = pluginCategory;
        PluginType = pluginType;
    }
}

[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class PluginAttribute2 : ExportAttribute, IPluginAttributeView
{
    public string PluginName { get; set; }
    public string PluginConfigurationName { get; set; }
    public string PluginCategory { get; set; }
    public Type PluginType { get; set; }

    public PluginAttribute2(string pluginName, string pluginConfigurationName, string pluginCategory, Type pluginType) : base(pluginType)
    {
        PluginName = pluginName;
        PluginConfigurationName = pluginConfigurationName;
        PluginCategory = pluginCategory;
        PluginType = pluginType;
    }
}

public class PluginAttribute
{
    public string PluginName { get; set; }
    public string PluginConfigurationName { get; set; }
    public string PluginCategory { get; set; }
    public Type PluginType { get; set; }

    public PluginAttribute(IPluginAttributeView view)
    {
        PluginName = view.PluginName;
        PluginConfigurationName = view.PluginConfigurationName;
        PluginCategory = view.PluginCategory;
        PluginType = view.PluginType;
    }
}


public interface IMagic1
{
    void DoMagic1();
}

public interface IMagic2
{
    void DoMagic2();
}

[PluginAttribute1("PluginName1", "PluginConfig1.json", "Magic1", typeof(IMagic1))]
[PluginAttribute2("PluginName2", "PluginConfig2.json", "Magic2", typeof(IMagic2))]
public class DoSomeMagic : IMagic1, IMagic2
{
    public void DoMagic1()
    {

    }

    public void DoMagic2()
    {

    }
}

I found the solution after digging through many MEF related blogs and articles. 在浏览了许多与MEF相关的博客和文章之后,我找到了解决方案。 The problem seemed that the imported MetaData is of type IDictionary<string, object . 问题似乎是导入的MetaData的类型为IDictionary<string, object I hope it helps some that may have struggled with similar issue: 我希望它可以帮助一些可能遇到类似问题的人:

class Program
{
    static void Main(string[] args)
    {
        var program = new Program();
        program.Test();
    }

    private void Test()
    {
        //Export
        var catalog = new AssemblyCatalog(this.GetType().Assembly);
        var container = new CompositionContainer(catalog);
        container.ComposeParts(this);

        //Import Meta Data
        var imports = container.GetExports<IMagic1, PluginAttributeView>().Select(e => e.Metadata.Attributes).ToList();

        var results = new List<PluginAttribute>();
        foreach (var import in imports)
        {
            foreach (var plugin in import)
            {
                if (plugin.PluginType.Equals(typeof(IMagic1)))
                {
                    results.Add(plugin);
                }
            }
        }
    }
}

public interface IPluginAttributeView
{
    string PluginName { get; set; }
    string PluginConfigurationName { get; set; }
    string PluginCategory { get; set; }
    Type PluginType { get; set; }
}

public class PluginAttributeView
{
    public List<PluginAttribute> Attributes { get; set; }

    public PluginAttributeView(IDictionary<string, object> aDict)
    {
        string[] p1 = aDict["PluginName"] as string[];
        string[] p2 = aDict["PluginConfigurationName"] as string[];
        string[] p3 = aDict["PluginCategory"] as string[];
        Type[] p4 = aDict["PluginType"] as Type[];

        Attributes = new List<PluginAttribute>();
        for (int i = 0; i < p1.Length; i++)
        {
            Attributes.Add(new PluginAttribute(p1[i], p2[i], p3[i], p4[i]));
        }
    }
}

[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
public class PluginAttribute : ExportAttribute, IPluginAttributeView
{
    public string PluginName { get; set; }
    public string PluginConfigurationName { get; set; }
    public string PluginCategory { get; set; }
    public Type PluginType { get; set; }

    public PluginAttribute(string pluginName, string pluginConfigurationName, string pluginCategory, Type pluginType) : base(pluginType)
    {
        PluginName = pluginName;
        PluginConfigurationName = pluginConfigurationName;
        PluginCategory = pluginCategory;
        PluginType = pluginType;
    }
}

public interface IMagic1
{
    void DoMagic1();
}

public interface IMagic2
{
    void DoMagic2();
}

[PluginAttribute("PluginName1", "PluginConfig1.json", "Magic1", typeof(IMagic1))]
[PluginAttribute("PluginName2", "PluginConfig2.json", "Magic2", typeof(IMagic2))]
public class DoSomeMagic : IMagic1, IMagic2
{
    public void DoMagic1()
    {

    }

    public void DoMagic2()
    {

    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM