MEF 编程指南(四):声明导入
组合部件通过 [System.ComponentModel.Composition.ImportAttribute] 特性声明导入。类似于导出,也有几种不同的方法声明导入,即通过:字段(Fields)、属性(Properties)和构造器参数(Constructor Parameters)。
属性导入(Property Imports)
为了向属性导入值,使用 [System.ComponentModel.Composion.ImportAttribute] 特性标识。如下例中导入 IMessageSender。
[Import] public IMessageSender MessageSender { get; set; }
构造器参数(Constructor Parameters)
也可以通过构造器参数指定导入。这意味着为每个导入添加构造器参数,而不必为每个属性添加导入。使用构造器参数导入,遵循以下几点。
1. 构造器添加 [System.ComponentModel.Compostition.ImportingConstructorAttribute] 特性 。
2. 为每个导入添加构造器参数。
2. 为每个导入添加构造器参数。
例如:在 Program 类的构造器中导入 MessageSender
[ImportingConstructor] public Program(IMessageSender messageSender) { }
参数导入(Parameter Imports)
有几种不同的方式在构造器上定义导入。
1. 隐式导入 - 默认情况下,容器会使用参数类型确认契约。例如:下面的代码,将使用 IMessageSender 契约。
2. 显示导入 - 如果想指定导入契约,在相应参数上添加 [System.ComponentModel.Composition.ImportAttribute] 特性。
字段导入(Field Imports)
MEF 也支持直接为字段导入值。
[Import] private IMessageSender _messageSender;
注意:在完全信任(Full Trust)的时候支持导入或者导出私有成员(字段、属性和方法),但是部分信任(Medium/Partial)可能会出问题。
缺省导入(Optional Imports)
MEF 允许指定缺省导入。当启用它,如果类型可用容器会提供导出,否则将导入设置为 Default<T>。为了得到一个缺省导入,在导入上设置 AllowDefault=true。如下例:
OrderController 缺省导入一个 Logger。如果 Logger 不存在,会设置 private _logger 字段为 DefaultLogger 实例,否则使用导入的 Logger。
导入集合(Importing Collections)
除了单一导入以外,也可使用 ImportMany 特性导入集合。这意味着所有特定的契约实例都会被容器导入。
MEF 部件也可以支持重排(Recomposition)。这意味着容器中新的导出变得可用,集合会自动更新为新的设置。例如:下面的 Notifier 类导出 IMessageSender 集合。这意味着如果容器中有3个可用的 IMessageSender 导出,在组合时候会被推送到 Senders 属性。
public class Notifier { [ImportMany(AllowRecomposition=true)] public IEnumerable<IMessageSender> Senders { get; set; } public void Notify(string message) { foreach (IMessageSender sender in Senders) { sender.Send(message); } } }
IPartImportsSatisfiedNotification 接口
某些情况下,在 MEF 对于类的实例的导入过程完成时候获得通知是非常重要的。如果要获得通知,实现 [System.ComponentModel.Composition.IPartImportsSatisfiedNotification] 接口。这个接口仅有一个方法:在类实例结合完成时候,OnImportsSatisfied 被调用。
public void OnImportsSatisfied() { // when this is called, all imports that could be satisfied have been satified. }
原文地址: