簡體   English   中英

MEF,我可以導出/導入具有多個MetaDataAttribute裝飾的類嗎?

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

如何使以下代碼起作用? 拋出一個錯誤,說有兩個具有相同名稱的元數據屬性,盡管我不明白為什么。

錯誤消息如下:

System.ComponentModel.Composition.dll中發生了類型為'System.InvalidOperationException'的未處理異常

附加信息:成員或類型'ConsoleApplication2.DoSomeMagic'包含多個名為'PluginName'的元數據條目。 元數據條目可以來自ExportMetadataAttribute或來自自定義元數據屬性的屬性。 刪除重復的條目,或者啟用名稱為“ 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()
    {

    }
}

在瀏覽了許多與MEF相關的博客和文章之后,我找到了解決方案。 問題似乎是導入的MetaData的類型為IDictionary<string, object 我希望它可以幫助一些可能遇到類似問題的人:

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