Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/273.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# MEF,我可以导出/导入具有多个MetaDataAttribute装饰的类吗?_C#_Dependency Injection_Inversion Of Control_Metadata_Mef - Fatal编程技术网

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

C# MEF,我可以导出/导入具有多个MetaDataAttribute装饰的类吗?,c#,dependency-injection,inversion-of-control,metadata,mef,C#,Dependency Injection,Inversion Of Control,Metadata,Mef,如何使以下代码正常工作?它抛出一个错误,说有两个相同名称的元数据属性,尽管我不明白为什么 错误消息如下所示: System.ComponentModel.Composition.dll中发生类型为“System.InvalidOperationException”的未处理异常 其他信息:成员或类型“ConsoleApplication2.DoSomeMagic”包含多个名为“PluginName”的元数据项。元数据项可能来自ExportMetadataAttribute或自定义元数据属性的属性。

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

错误消息如下所示:

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相关的博客和文章后,我找到了解决方案。问题似乎是导入的元数据属于IDictionary类型我在翻阅了许多与MEF相关的博客和文章后找到了解决方案。问题似乎是导入的元数据的类型为IDictionaryEdit I,其中包含引发问题的完整代码示例。当您说要按接口类型查询时,是要按导出部件的接口类型查询,还是按附加元数据的接口类型查询?@Matt,通过上面的代码,我希望能够在import1中仅检索包含匹配类型属性的属性的元数据,例如,我想在import1中获取一个元数据集合,其中PluginType属性的类型为IMagic1。编辑我包含了一个引发问题的完整代码示例。当您说要按接口类型查询时,是按导出部件的接口类型查询,还是按所附元数据的接口类型查询?@Matt,使用上面的代码,我希望能够在import1中仅检索包含匹配类型属性的属性的元数据,因此,例如,我希望在import1中获取一个元数据集合,其中PluginType属性的类型为IMagic1。非常好!无论如何,不需要第二个自定义属性。注意,在MEF中,导入是由合成容器在幕后注入的部分。另外,您不需要在程序类中调用ComposeParts,因为它没有导入/导出。太棒了!无论如何,不需要第二个自定义属性。注意,在MEF中,导入是由合成容器在幕后注入的部分。此外,您不需要在程序类中调用ComposeParts,因为它没有导入/导出。
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()
    {

    }
}