MEF学习系列(2): 导入(Import)和导出(Export)
来源:互联网 发布:淘宝一次性粥杯 编辑:程序博客网 时间:2024/06/03 19:24
前言:
MEF不同于其他IOC容器(如:Castle)很重要的原因在于它使用了特性化编程模型,何为特性化变成模型,简单索命两个概念:“特性”和“编程模型”
特性(Attribute):举例来说就是我们在开发过程中在类上标记的如:[Serializable]的标签。
编程模型(Programming Model):MEF中的编程模型是定义MEF所操作的概念性对象集的特定方法。MEF默认使用特性化编程模型,但是用户也可以自定义编程模型。
导入(Import),导出(Export)是MEF扩展性机制实现的基础,是非常重要的两种部件。MEF中导入、导出部件均是通过特性来确定的(如:标记有[Export]特性的我们称之为导出部件)。本文简单的介绍下MEF中的导入和导出。
导入和导出基础:
在上一篇文章中我们说过导出提供的是服务,而导入则使用或者说接入这些服务。一般情况,导入使用Import特性声明,导出使用Export特性声明。Export特性可修饰类、字段、属性或方法,而Import特性可修饰字段、属性或构造函数参数。导入和导出的匹配必须要有相同的Contract,Contract有两部分组成:ContractName(名称)和ContractType(类型),只有名称和类型完全相同,才会认为导出能够满足特定导入。如:
//注意一定要建立一个接口作为导入导出的typeof类型关联使用 public interface ILog { void Log(Exception ex); } //导出的类型为ILog[Export(typeof(ILog))] public class FileLog : ILog //也就是说继承与哪个接口那么导出的类型也就是哪个接口类型 { public void Log(Exception ex) { } } public class MyClass { //导入的类型默认为ILog, 可以与导出匹配[Import(typeof(ILog))] public ILog MyLog //注意这里的属性类型是ILog,导入的是什么typeof的这个属性也应该是什么类型的 { get; set; } }
导入的类型:
MEF中导入的类型包括:动态导入、延迟导入、必备导入和可选导入。
动态导入:使用dynamic关键字导入,协定类型从dynamic关键字推断而出,则它将与任何协定类型匹配。所以在使用倒台导入时必须指定协定名称,否则将未匹配任何导入
public class MyClass { [Import("MyLog")] //这里必须要有“”里的这个导入协定的名称 public dynamic MyLog { get; set; } }
延迟导入:我们知道延迟加载,那么延迟导入通延迟加载的作用一样:导入和导出匹配时不会立即实例化对象,延迟导入需要使用Lazy<T>来声明导入:
public class MyClass { [Import] public Lazy<ILog> MyLog { get; set; } //延迟导入类型为ILog接口类型的Export到该属性 }
必备导入:在实际工作中我们经常会用到依赖注入,通过构造函数将对象注入到本类中时依赖注入的一种形式,MEF也可以完成构造注入。
导出部件通常由组合引擎/容器创建,默认情况下,在创建部件时,组合引擎将使用无参数的构造函数。要想使用自定义构造函数完整对象的注入需要使用特性:ImportingConstruction。使用必备导入时必须同时提供默认构造和ImportingConstruction的构造方法,否则将出错。MEF允许导入和导出的循环依赖。
public class MyClass { private ILog _myLog; public MyClass() { } [ImportingConstructor]//在构造函数里导入使用时用该特性标示 public MyClass(ILog myLog) { _myLog = myLog; } }
可选导入:在MEF中如果导入得不到匹配将会组合失败,在需要容错的情况下,可以使用AllowDefault属性指定导入为可选:[Import(AllowDefault = true)]。这样即使导入没有得到匹配也不会影响组合容器对部件的组合。
导入多个对象:导入和导出可以支持一对多的关系,使用ImportMany特性可以导入多个服务(导出),使用ImportMany标记的导入始终是可选导入。
public class MyClass { [ImportMany] public IEnumerable<ILog> MyLogs { get; set; } //导入多个对象,所以这里的类型是IEnumerable<ILog> }
导入和导出的继承
导入的继承:导入始终由子类继承,子类拥有和父类相同的导入。
导出的继承:使用Export特性的导出部件始终不能被继承,如果想要导出部件可以被继承需要使用关键字:InheritedExport,子类将提供与父类相同的导出(包括ContractName和ContractType)。但是InheritedExport只能标记在类上,也就是说成员导出永远不能被继承。
- MEF学习系列(2): 导入(Import)和导出(Export)
- MEF学习系列(3): 导入(Import)和导出(Export)之 元数据(Metadata)和自定义导出(Custom Export)
- Import/Export导入导出数据(理论)
- 实战MEF(2):导出&导入
- Dll的导入导出(export与import)
- MEF学习系列(1) MEF是什么
- MEF应用(3) 导入导出续
- Django点滴(2)xadmin+django-import-export导入导出的实现
- MEF学习系列(6): 在Silverlight中应用MEF
- DB2 数据的导入(Import) 导出(Export)(Load)
- DB2数据的导入(Import) 导出(Export)(Load)
- DB2数据的导入(Import) 导出(Export)(Load)
- DB2数据的导入(Import) 导出(Export)(Load)
- DB2数据的导入(Import) 导出(Export)(Load)
- Drupal 7 节点数据(Node)导入/导出(Import/Export)
- 【Oracle】数据导入导出(expdp、impdp ;export、import)——用户模式
- 【Oracle】数据导入导出(expdp、impdp ;export、import)——用户模式
- MEF程序设计指南四:使用MEF声明导出(Exports)与导入(Imports)
- (笔记)C++ Primer/第五章 表达式
- C++中的类模板详细讲述
- 嵌入式ssh实现
- 【PAT】1019. General Palindromic Number (20)
- 多线程GCD的使用
- MEF学习系列(2): 导入(Import)和导出(Export)
- mcp2510驱动备份
- Android Support V7 包中 ActionBar的使用 (2) 分离式 ActionBar
- Android感应检测Sensor(简单介绍)
- Java学习之道:Java中Object... 代表什么意思
- 程序猿,该在一个公司呆多久?
- 隐藏StatusBar
- 如何学习Java,Net,Android等编程技术
- SQL字段和值一起输出