MEF学习系列(3): 导入(Import)和导出(Export)之 元数据(Metadata)和自定义导出(Custom Export)

来源:互联网 发布:仿真软件multisim14 编辑:程序博客网 时间:2024/06/10 19:49

前言

在上一篇中,我们简单的介绍了导入好导出的基础知识以及一些基本用法,本篇将介绍一下在导出中经常使用到的两种技巧(其实就是MEF提供的两种特性):元数据(Metadata)和自定义导出(Custom Export)。

元数据

在MEF中,导出可提供自身的一些附加信息,我们称之为“元数据”。可通过元数据将导出的一些信息、属性传递给导入。上一篇介绍导入的时候提到了ImportMany,在ImportMany的时候有可能需根据特定的条件过滤一些匹配的导出,这时我们可以利用导出的元数据作依据。此外,由于导入部件可以根据元数据来决定要使用哪些导出,或收集有关导出的信息而不必构造导出。因此,导入必须为延迟导入才能使用元数据

使用元数据需要定义一个称为“元数据视图”的接口,元数据视图中有且只能定义只读的属性,可以使用特性[DefaultValue]给属性默认值,元数据视图中定义的所有属性在使用时都必须赋值,否则使用该元数据的导出将于任何导入匹配失败,当然我们也可以使用[DefaultValue]设置默认值,这样被[DefaultValue]修饰的属性便可以认为是可选属性。例:

public interface ILogMetadata { [DefaultValue("FileLog")] string LogType { get; } string Name { get; } }


使用元数据视图修饰的导出:

[Export(typeof(ILog))] [ExportMetadata("Name", "FileLog")] [ExportMetadata("LogType", "FileLog")] public class FileLog : ILog { }


注意:特性ExportMetadata的参数第一个为属性名称,第二个是属性的值。组合容器在组合部件时会自动匹配所有的元数据视图,如果有符合的元数据视图则该导出部件视为匹配成功。

匹配导入(匹配含有元数据修饰的导出,导入需要使用延时加载):

public class MyLog { [Import] public Lazy<ILog, ILogMetadata> singleLog { get; set; } [ImportMany] public IEnumerable<Lazy<ILog, ILogMetadata>> logs; }


自定义导出

在上面的示例中我们可能会想,当元数据视图的必须属性有很多时,我们是不是得使用很多的[ExportMetadata]来修饰导出,另外元数据视图的写法也很容易出错,其实MEF中可以对Export和InheritedExport进行扩展,用于将元数据封装到自定义特性中。

自定义特性可以指定ContractType、ContractName或任何其他元数据。为了定义自定义特性,必须使用MetadataAttribute特性来修饰继承自ExportAttribute(或InheritedExportAttribute)的类。

[MetadataAttribute] [AttributeUsage(AttributeTargets.Class,AllowMultiple=true)] //指定特性的作用域 public class FileLogExportAttribute:ExportAttribute { public FileLogExportAttribute(string logType):base(typeof(ILog)) { LogType = logType; Name = "FileLog"; } public string LogType{get;private set;} public string Name{get;private set;} }

使用自定义导出修饰前面的导出:

[FileLogExport("FileLog")] public class FileLog : ILog { }


使用自定义导出的特性,ContractType是隐式定义的。

在必须将大量的相同元数据(例如,作者或版权信息)应用于多个部件的情况下,使用自定义特性可以节约大量的时间和重复工作。此外,可以创建自定义特性的继承树来为变体留出余地。

若要在自定义特性中创建元数据,您可以使用DefaultValue特性。如果此特性应用于自定义特性类中的属性,它将指定修饰的属性是可选的,并且不必由导出程序提供。如果未提供属性的值,则将为属性分配其属性类型的默认值(通常为null、false或0)。

最后,MEF中的导入是不能进行自定义的,但MEF中导出和元数据的配合使得导出更加里干活。

参考地址: http://msdn.microsoft.com/zh-cn/library/ee155691.aspx

原创粉丝点击