首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >自定义MEF和AllowMultiple=true将导致复制。

自定义MEF和AllowMultiple=true将导致复制。
EN

Stack Overflow用户
提问于 2013-07-03 21:19:34
回答 1查看 4.3K关注 0票数 4

我希望导出具有多个元数据选项的类型Foo

代码语言:javascript
复制
public interface IFoo
{
    void Do ();
}

[ExportFoo ("Bar", "1.0")]
[ExportFoo ("Baz", "1.0")]
[ExportFoo ("Baz", "2.0")]
public class Foo : IFoo
{
    public void Do () {}
}

我已经以这种方式声明了ExportFooAttribute

代码语言:javascript
复制
public interface IFooMeta
{
    string Name { get; }
    string Version { get; }
}

[MetadataAttribute, AttributeUsage (AttributeTargets.Class, AllowMultiple = true)]
public class ExportFooAttribute : ExportAttribute, IFooMeta
{
    public string Name { get; private set; }
    public string Version { get; private set; }

    public ExportFooAttribute (string name, string version) : base(typeof(IFoo))
    {
        Name = name;
        Version = version;
    }
}

根据文档,当AllowMultiple设置为true时,元数据实际上包含原始元数据的属性数组,因此我以这种方式导入类型:

代码语言:javascript
复制
public interface IFooMultiMeta
{
    string[] Name { get; }
    string[] Version { get; }
}

public class Program
{
    [ImportMany]
    public List<Lazy<IFoo, IFooMultiMeta>> Foos { get; set; }

    private static void Main ()
    {
        new Program().MainInternal();
    }

    private void MainInternal ()
    {
        new CompositionContainer(new AssemblyCatalog(Assembly.GetExecutingAssembly())).ComposeParts(this);
        foreach (Lazy<IFoo, IFooMultiMeta> lazyFoo in Foos)
            for (int i = 0; i < lazyFoo.Metadata.Name.Length; i++)
                Console.WriteLine("* {0} {1}", lazyFoo.Metadata.Name[i], lazyFoo.Metadata.Version[i]);
        Console.WriteLine(Equals(Foos[0].Metadata, Foos[1].Metadata));
        Console.ReadKey();
    }
}

我期望得到一个包含3个值数组的元数据的Foo实例。然而,我得到的是:

代码语言:javascript
复制
* Baz 2.0
* Baz 1.0
* Bar 1.0
* Baz 2.0
* Baz 1.0
* Bar 1.0
* Baz 2.0
* Baz 1.0
* Bar 1.0
False

更糟糕的是,元数据实例是不同的,所以我甚至不能正确地过滤掉重复的。

问题:如何正确地导出一个类以满足元数据属性的多个组合?

完整样本:http://pastebin.com/WyjN95gr

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-07-08 09:08:50

这三个导出的原因是您从ExportAttribute派生自定义导出元数据。这意味着每件装饰品都有不同的出口。三件装饰品导致三件出口。

我不知道为什么每个导出都有所有的{Name,Version}对。

要克服这三个导出,您可以更新您的自定义属性以从属性派生:

代码语言:javascript
复制
[MetadataAttribute, AttributeUsage (AttributeTargets.Class, AllowMultiple = true)]
public class ExportMetaFooAttribute : Attribute, IFooMeta
{
    public string Name { get; private set; }
    public string Version { get; private set; }

    public ExportFooAttribute (string name, string version)
    {
        Name = name;
        Version = version;
    }
}

我已经将它重命名为ExportMetaFooAttribute,因为它不是导出属性,而是导出元数据属性。

然后将Foo类更改为:

代码语言:javascript
复制
[Export(typeof(IFoo))]
[ExportMetaFoo("Bar", "1.0")]
[ExportMetaFoo("Baz", "1.0")]
[ExportMetaFoo("Baz", "2.0")]
public class Foo : IFoo
{
    public void Do ()
    {}
}

正如您现在看到的,我们需要额外的ExportAttribute来指定需要导出该类。

票数 9
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17458304

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档