博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
我学MEF系列(2):导入(Import)和导出(Export)
阅读量:5161 次
发布时间:2019-06-13

本文共 2430 字,大约阅读时间需要 8 分钟。

前言:

MEF不同于其他IOC容器(如:Castle)很重要的原因在于它使用了特性化编程模型,何为特性化编程这里不细究,简单说明下两个概念:“特性”和“编程模型”:

  特性(Attribute):举例来说就是我们在开发过程中在类上标记的如:[Serializable]的标签。

  编程模型(Programming Model):MEF中的编程模型是定义 MEF 所操作的概念性对象集的特定方法。MEF默认使用特性化编程模型,但是用户也可自定义编程模型。

  导入(Import),导出(Export)是MEF扩展性机制实现的基础,是非常重要的两种部件。MEF中导入、导出部件均是通过特性来确定的(如:标记有[Export]特性的我们称之为导出部件)。本文简单的介绍下MEF中得导入和导出。

导入和导出基础:

  在上一篇文章中我们说过导出提供的是服务,而导入则使用或者说接入这些服务。一般情况,导入使用 Import特性声明 ,导出使用 Export 特性声明。 Export 特性可修饰类、字段、属性或方法,而 Import 特性可修饰字段、属性或构造函数参数。导入和导出的匹配必须要有相同的Contract,Contract有两部分组成:ContractName(名称)和ContractType(类型),只有名称和类型都完全相同,才会认为导出能够满足特定导入。如:

View Code
1 public interface ILog  2 {
3 void Log(Exception ex); 4 } 5 6 //导出的类型为ILog[Export(typeof(ILog))] 7 pulic class FileLog:ILog 8 {
9 public void Log(Exception ex) 10 {
11 } 12 } 13 14 pulic class MyClass 15 {
16 //导入的类型默认为ILog,可以与导出匹配 [Import] 17 pulic Ilog MyLog 18 {
19 get; 20 set; 21 } 22 }

导入的类型:

MEF中导入的类型包括了:动态导入、延迟导入、必备导入和可选导入。

动态导入:使用dynamic关键字进行导入,协定类型从 dynamic 关键字推断而出,则它将与任何协定类型匹配。所以在使用倒台导入时必须指定协定名称,否则将未匹配任何导出

1 public class MyClass 2 {
3 [Import(“MyLog”)] 4 public dynamic MyLog{ get; set; } 5 }

延迟导入:我们知道延迟加载,那么延迟导入同延迟加载的作用一样:导入和导出匹配时不会立即实例化对象,延迟导入需要使用Lazy<T>来声明导入:

1 public class MyClass 2 {
3 [Import] 4 public Lazy
MyLog { get; set; } 5 }

必备导入:在实际工作中我们经常会用到依赖注入,通过构造函数将我对象注入到本类中是依赖注入的一种形式,MEF也可以完成构造注入。

    导出 部件通常由组合引擎/容器创建,默认情况下,在创建部件时,组合引擎将使用无参数的构造函数。要想使用自定义构造函数完整对象的注入需要使用特性:ImportingConstructor。使用必备导入时必须同时提供默认构造和ImportingConstructor的构造方法,否则将出错.MEF允许导入和导出的循环依赖。

1 public class MyClass  2 {
3 private ILog _myLog; 4 5 public MyClass() { } 6 7 [ImportingConstructor] 8 public MyClass(ILog myLog) 9 {
10 _myLog = myLog; 11 } 12 }

可选导入:在MEF中如果导入得不到匹配将会组合失败,在需要容错的情况时,可以使用AllowDefault 属性指定导入为可选:[Import(AllowDefault = true)]。这样即使导入没有得到匹配也不会影响组合容器对部件的组合。

导入多个对象:导入和导出可以支持一对多的关系,使用ImportMany特性可以导入多个服务(导出),使用ImportMany标记的导入始终是可选导入。

1 public class MyClass 2 {
3 [ImportMany] 4 public IEnumerable
MyLogs { get; set; } 5 }

导入和导出的继承

导入的继承:导入始终由子类继承,子类拥有和父类相同的导入。

导出的继承:使用Export特性的导出部件始终不能被继承,如果想要导出部件可以被继承需要使用关键字:InheritedExport,子类将提供与父类相同的导出(包括ContractName和ContractType)。但是InheritedExport只能标记在类上,也就是说成员导出永远不能被继承。

后记:导入和导出相关的概念还包括元数据,以及自定义导出相关知识,将在下一篇中详细介绍。

本文参考:

转载于:https://www.cnblogs.com/pszw/archive/2011/12/04/2276241.html

你可能感兴趣的文章
数据库误删了数据再也不用跑路了,
查看>>
一、BOM 二、DOM
查看>>
Docker的部署安装(CentOS)
查看>>
ModelMap和ModelAndView区别
查看>>
虚拟机vmware下安装Ghost XP——正确的解决方案
查看>>
eclipse下:selenium+python自动化之Chrome driver
查看>>
洛谷P3006 [USACO11JAN]瓶颈Bottleneck(堆模拟)
查看>>
mysql 创建存储过程报错
查看>>
C++笔记
查看>>
移动端
查看>>
stat~~~访问文件状态的利器
查看>>
SORT--不要仅限于题目中
查看>>
面试题46:求1+2+...+n
查看>>
Cscope 安装和使用
查看>>
Rails常用插件
查看>>
基于Dockerfile 构建redis5.0.0(包括持久化)及RedisDestopManager 监控
查看>>
Git 一些常用命令
查看>>
巧用linux服务器的/dev/shm/
查看>>
CSS 选择器大全
查看>>
FJOI省队集训 florida
查看>>