MEF学习笔记(4):声明导入

声明导入

组成部件声明导入[System.ComponentModel.Composition.ImportAttribute]特性。跟导出类似,有几个不同的方法即是通过字段,属性和构造函数。

 属性导入

为了导入一个属性值,用[System.ComponentModel.Composition.ImportAttribute]声明属性。例如下面的代码片段导入一个IMessageSender

  class Program
  {
    [Import]
    public IMessageSender MessageSender { get; set; }
  }

构造函数参数

你也可以通过构造函数的参数指定导入。这意味着不必给每个导入添加属性,你只需要为导入给构造函数添加参数。为了使用这个,按照下面的步骤进行:

  1. 添加一个[System.ComponentModel.Composition.ImportingConstructorAttribute] 特性到要被MEF使用的构造函数。
  2. 为每个导入添加参数到构造函数。

例如下面的代码在Program类的构造函数导入一个message sender

  class Program
  {
    [ImportingConstructor]
    public Program(IMessageSender messageSender) 
    {
       ...
    }
  }

参数导入

有几个不同的方法在构造函数定义导入

1、隐式导入-默认容器会使用参数的类型去识别契约。例如在下面的借代码,IMessageSender契约会被使用。

  class Program
  {
    [ImportingConstructor]
    public Program(IMessageSender messageSender) 
    {
    }
  }

2、显式导入-如果你想要指定被导入的契约,添加[System.ComponentModel.Composition.ImportAttribute]特性到参数。

 

字段导入

MEF也支持直接导入字段值。

  class Program
  {
    [Import]
    private IMessageSender _messageSender;
  }

注意:注意导入或导出私有成员(字段,属性和方法)当在完全信任状态下支持,在中间/局部信息状态可能有问题。

 

可选择导入

MEF允许你指定一个导入是可选的。当你允许这个,如果它是有效的容器会装备这个导出,否则它会设置导入是Default(T).为了使一个导入可选,在导入里设置AllowDefault=true,像下面一样:

[Export]
public class OrderController {
  private ILogger _logger;

  [ImportingConstructor]
  public OrderController([Import(AllowDefault=true)] ILogger logger) {
    if(logger == null)
      logger = new DefaultLogger();
    _logger = logger;
  }
}

OrderController可选导入logger。如果logger不存在,它会设置private _loggerDefaultLogger 实例,否则它会使用导入的logger。

 

导入集合

除了单独导入外,你可以用ImportMany特性导入集合。这意味着所有指定契约的实例会从容器中导入。

MEF部件也可以支持重构。这意味着在容器里新的导出变得可行,集合在新设置里被自动更新。例如下面的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 class Program : IPartImportsSatisfiedNotification
 {
    [ImportMany]
    public IEnumerable<IMessageSender> Senders {get; set;}

    public void OnImportsSatisfied() 
    {
      // when this is called, all imports that could be satisfied have been satisfied.
    } 
  }

 

 

posted @ 2012-04-24 15:43  王春明  阅读(726)  评论(0编辑  收藏  举报