2017-10-07 111 views
2

我认为幕后的ImportAttributeImportManyAttribute应该使用MEF的一些核心方法来获取与导出类型的实际实例配对的导出元数据。使用这些属性与以下设置正常工作:获取导出的元数据而不使用MEF中的ImportAttribute或ImportManyAttribute?

//the metadata interface 
public interface IMetadata { 
    string Name {get;} 
} 
//the custom ExportAttribute 
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)] 
[MetadataAttribute] 
public class CustomExportAttribute : ExportAttribute, IMetadata { 

    public string Name {get;set;} 
} 
//the class which need to be exported (both value and metadata) 
[CustomExport(Name = "someName")] 
public class A { 
} 
//the class which imports the exported value and metadata 
[Export] 
public class B { 
    [Import] 
    public Lazy<A, IMetadata> AData {get;set;} 
} 

现在得到B的出口值的时候,我可以通过IMetadata接口的A及其相关元数据正确导出例如浏览AData,就像这样:

var ac = new AggregateCatalog(); 
ac.Catalogs.Add(new DirectoryCatalog(".")); 
var c = new CompositionContainer(ac); 
var b = c.GetExportedValue<B>(); 
var data = b.AData.Value;//some instance of A here 
var mdata = b.AData.Metadata;//some metadata of A here 

但是我不想在这种情况下使用B这个类,我怎么能得到A的实例和它的元数据的导出对呢?因为没有使用任何类(如B),所以在这种情况下也不使用属性ImportAttribute。 以下是我已经试过:

var ac = new AggregateCatalog(); 
ac.Catalogs.Add(new DirectoryCatalog(".")); 
var c = new CompositionContainer(ac); 
var a = c.GetExportedValue<Lazy<A,IMetadata>>(); 

上面最后一行抛出异常ImportCardinalityMismatchException,像这样:

出口没有发现匹配的约束:ContractName System.Lazy(测试。 A,Test.IMetadata)RequiredTypeIdentity System.Lazy(Test.A,Test.IMetadata)

我相信,必须有某种方式来获得出口值(对类型实例及其元数据)的情况下直接使用一个虚拟类,其中ImportAttribute用于存储该类某些属性中的导出值。

请帮我解决这个问题,我还在开始使用MEF和Prism。谢谢你的帮助!

回答

1

确实有一种方法!不需要导入另一个班级的出口。只需使用GetExport < T,TMetadataView>方法。基于您的代码我把它仅仅通过增加工作:

var wow = c.GetExport<A, IMetadata>(); 

这将返回只是你想要的,一个懒惰< T,TMetadataView>

希望这有助于!

+0

好吧,它有点隐藏,它真的有帮助,谢谢。我关心的问题已经很遥远,因为我现在已经参与其他问题,我还没有测试过,但我相信它应该工作! – Hopeless

相关问题