zoukankan      html  css  js  c++  java
  • 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.
        } 
      }
  • 相关阅读:
    Eclipse中自动提示的方法参数都是arg0,arg1的解决方法
    eclipse 下找不到或无法加载主类的解决办法
    将博客搬至CSDN
    java接口中定义成员变量
    重写与重载
    多位数每一位个系数:个位num%10;十位num/10%10.......
    输出 n=6 的三角数字阵(JAVA基础回顾)
    二维数组的遍历之查漏补缺
    For循环打印正三角,倒三角,菱形
    JAVA的continue用法
  • 原文地址:https://www.cnblogs.com/wangchunming/p/2468191.html
Copyright © 2011-2022 走看看