MEF系列二:定义部件(Parts)和契约(Contracts)

来源:互联网 发布:nginx的特点 编辑:程序博客网 时间:2024/06/06 16:38

组合部件(Parts)

部件(Part)在MEF中是一个可组合单元,组合部件导出服务为其它组合部件所需要,导入服务来自其它的组合部件。在MEF编程模型中,组合部件用System.ComponentModel.Composition.Import 和[System.ComponentModel.Composition.Export]来标识是导入还是导出。一个组合部件最少包含一个导出,部件通过手工指定或通过创建使用目录来添加到组合容器对象中,MEF附带的默认目录识别组合部件通过存在的导出属性

契约(Contracts)

组合部件不直接依赖于另一个,而是依赖于一个字符串标识契约。所有导出部件都有一个契约,所有导入声明它所需要的契约。组合容器对象使用导入的契约信息来匹配导出。如果没有明确指定契约,MEF将默认使用类型完全限定名称作为契约。如果类型是通过的,它将使用完全限定名称。

注:默认契约应该是一个类型,而不是一个字符串。尽管契约可以是一个任意的字符串,这可能导致歧义。例如"Sender"可能与在另一个库中实现了"Sender"重叠,出于这个原因,你需要指定一个字符串契约,建议契约名称应该包含公司名称空间限定的名称,例如"Contoso.Exports.Sender"。

下面代码片断,所有的导出契约都是相同的
namespace MEFSample {  [Export]  public class Exporter {...}  [Export(typeof(Exporter))]  public class Exporter1 {...}  [Export("MEFSample.Exporter")]  public class Exporter2 {...}}
接口/抽象契约
一个常见的模式是组合部件导出一个接口或抽象类型而不是一个具体类型。它允许导入跟导出的实现完全解耦,使得导入的关注点分离。例如下面你可以看到两个Sender实现导出IMessageSender,Notifier类导入IMessageSender对象的集合,IMessageSender可以调用它的Send()方法,新的Message Senders现在可以很容易被添加到系统。

[Export(typeof(IMessageSender))]  public class EmailSender : IMessageSender {    ...  }  [Export(typeof(IMessageSender))]    public class TCPSender : IMessageSender {    ...  }  public class Notifier {    [ImportMany]    public IEnumerable<IMessageSender> Senders {get; set;}    public void Notify(string message) {      foreach(IMessageSender sender in Senders)         sender.Send(message);    }   }

契约程序集

一种常见的模式,当部署契约集合构建MEF可扩展应用程序,契约集合只是包含填充用于扩展你的应用程序的契约类型,一般这些将会是接口,也有可能是抽象类,另外契约集合也有可能包含导入可能会使用的元数据视图接口,以及任何自定义MEF导出属性。

注:你必须指定明确接口类型(IMessageSender)作为导出,否则类型(EmailSender)本身将被导出

注:以上只是为了方便我自己学习记录,有些地方翻译不到位,唯恐误导读者,如有需要请阅读原文http://mef.codeplex.com/wikipage?title=Parts&referringTitle=Guide

0 0