MEF,我可以导出/导入具有多个MetaDataAttribute装饰的类吗? [英] MEF, can I export/import classes with multiple MetaDataAttribute decorations?

查看:62
本文介绍了MEF,我可以导出/导入具有多个MetaDataAttribute装饰的类吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何使以下代码正常工作?抛出一个错误,说有两个具有相同名称的元数据属性,尽管我不明白为什么.

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.

错误消息如下:

System.ComponentModel.Composition.dll中发生了类型为'System.InvalidOperationException'的未处理异常

An unhandled exception of type 'System.InvalidOperationException' occurred in System.ComponentModel.Composition.dll

其他信息:成员或类型'ConsoleApplication2.DoSomeMagic'包含多个名为'PluginName'的元数据条目.元数据条目可以来自ExportMetadataAttribute或来自自定义元数据属性的属性.要么删除重复的条目,要么启用名称为"PluginName"的元数据条目,以允许通过ExportMetadataAttribute上的IsMultiple属性或自定义元数据属性上的AttributeUsage.AllowMultiple允许多个条目.

Additional information: Member or Type 'ConsoleApplication2.DoSomeMagic' contains multiple metadata entries with the name 'PluginName'. The metadata entries could be coming from the ExportMetadataAttribute or from a property of a custom metadata attribute. 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.

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()
    {

    }
}

推荐答案

在浏览了许多与MEF相关的博客和文章之后,我找到了解决方案.问题似乎是导入的MetaData的类型为IDictionary<string, object.我希望它能帮助一些可能遇到类似问题的人

I found the solution after digging through many MEF related blogs and articles. The problem seemed that the imported MetaData is of type 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()
    {

    }
}

这篇关于MEF,我可以导出/导入具有多个MetaDataAttribute装饰的类吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆