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. 为每个导入添加构造器参数。


例如:在 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.
        }

 

 
原文地址:
posted @ 2014-04-18 17:08  安布雷拉  阅读(820)  评论(0编辑  收藏  举报