• 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.
        } 
      }
  • 相关阅读:
    mysql 创建数据库的基本操作
    MySQL的数据类型 及注意事项
    在执行 pip install 时遇到错误:python setup.py egg_info Check the logs for full command output
    python3.8-运行jupyter 报raise NotImplementedError
    执行python 爬虫脚本时提示bs4.FeatureNotFound: Couldn't find a tree builder with the features you requested: lxml. Do you need to install a parser library?
    Python:lambda表达式和yield关键字理解与使用讲解
    百度paddle框架学习(二):使用经典VGG网络完成人脸口罩判别
    深度学习中的梯度
    C++ OpenCV学习笔记(持续更新)
    Tensorflow常见报错
  • 原文地址:https://www.cnblogs.com/wangchunming/p/2468191.html
Copyright © 2020-2023  润新知