前言

在前面的介绍中我们已经知道:导入和导出的匹配成功需要ContractType,ContractName,Metadata都匹配,这里我们还要介绍一个新的东西:创建策略(creation policy )。有时候我们在容器中的实例在每一个导入之间共享,即单例;有时候我们需要让每一个导入都拥有一个各自的实例,这在MEF中就是有创建策略决定的。

生命周期(Life Cycle),每一个MEF的部件在容器中都有自己的生命周期,何时创建,何时释放等。本文就主要介绍一下MEF中得创建策略和生命周期

创建策略

创建策略,其实就是组合容器决定如何创建部件。在组合容器组合部件时,如果导入和导出匹配成功,则组合容器会将导入成员的值设置成为导出的实例。因此,导出部件的创建策略决定了部件来源于何处:是现有实例还是新实例。

MEF的创建策略有:Shared(共享)和NonShared(非共享)。

使用Shared创建策略的部件将在每一个导入部件中共享实例。仅当容器中没有该部件的实例时才会创建新实例。使用共享策略创建的部件可以是提供服务的部件,以及较占用内存的部件。他们的内部状态应该尽可能少得受外界影响。

使用NonShared策略的部件在匹配每一个导入时都会有新的实例。这些部件的内部状态都是相互独立的,当某些部件需要保持特定的状态时可以使用这种策略。

MEF关于创建策略提供的特性有3种:Shared,NonShared,Any(请注意Any和Shared的区别,创建策略只有两种)。导入和导出的默认值都是Any。当导入导出都是用默认创建策略,或者都是用默认,MEF将默认创建策略为Shared。创建策略的匹配与否也决定了导出部件和导入能否成功匹配。以下情况可视为匹配成功:

1. 标记为Any的导出部件与Shared和NonShared的导入均能成功匹配;

2. 创建策略为Shared或NonShared的导出以及标记为Any的导入匹配成功;

3. 创建策略为Shared的导出只能与创建策略为Shared和标记为Any匹配成功;

4. 创建策略为NonShared的导出只能为Shared和标记为Any的导入匹配成功。

注意:

MSDN是这么表述的:
导入和导出的默认值均为 Any。 
指定 Shared 或 NonShared 的导出将仅与指定相同值或指定 Any 的导入匹配。 
同样,指定 Shared 或 NonShared 的导入将仅与指定相同值或指定 Any 的导出匹配。
如果导入和导出均指定 Any,或者未指定创建策略那么默认为 Any,则创建策略将默认为“共享“。

创建策略特性的用法:

//导入部件

[Import(RequiredCreationPolicy = CreationPolicy.Shared)]
//导出部件
[PartCreationPolicy(CreationPolicy.NonShared)]

请看一个简单的例子:

//定义导出部件,创建策略为非共享
[Export]
[PartCreationPolicy(CreationPolicy.NonShared)]
public class FileLog
{
public void WriteLog()
{
Console.Writeline("This is FileLog!");
}
} //定义导出部件,创建策略为非共享
[Export]
[PartCreationPolicy(CreationPolicy.Shared)]
public class DBLog
{
public void WriteLog()
{
Console.Writeline("This is DBLog!");
}
} public class MyClass
{
//成功匹配
[Import(RequiredCreationPolicy = CreationPolicy.NonShared)]
public FileLog MyFileLog1; //匹配失败
[Import(RequiredCreationPolicy = CreationPolicy.Shared)]
public FileLog MyFileLog2; //匹配成功
[Import]
public DBLog MyDBLog; }

注:到目前为止我们可以知道影响导出部件同导入部件成功匹配的主要因素大概有:ContractType(协定类型),ContractName(协定名称),Metadata(元数据),CetationPolicy(创建策略)。

生命周期

在MEF中,生命周期是比较复杂的,在MSDN中也只用一句话带过:

由于部件承载于组合容器中,因此其生命周期可能比普通对象更复杂。 部件可实现两个重要的生命周期相关接口:IDisposable 和 IPartImportsSatisfiedNotification。

容器本身实现了IDisposable,在容器Dispose方法被调用时,容器会对容器中得每一个部件调用Dispose方法。一般情况下,部件只有在容器释放时才会释放资源。联想到上面介绍的创建策略,有人不禁要问如果创建策略为非共享的部件过多,很占用很多资源,不过不用担心:容器提供了 ReleaseExport 方法。此方法可以释放导出部件,并对部件占用的资源进行释放。

如果部件实现了接口IPartImportsSatisfiedNotification ,当组合已完成并且部件的导入可供使用时,组合窗口将对部件调用接口中得方法OnImportsSatisfied。

IPartImportsSatisfiedNotification 包含一个名为 OnImportsSatisfied 的方法。 当组合已完成并且部件的导入可供使用时,组合窗口将对实现接口的任何部件调用此方法。 部件是组合引擎创建,用于满足其他部件的导入。 在设置好部件的导入之前,您无法执行任何依赖于部件构造函数中的导入值或对这些值进行操作的初始化,除非已通过使用 ImportingConstructor 特性将这些指定为必备。 此方法通常为首选方法,但在某些情况下,构造函数注入可能不可用。 在这些情况下,可以在 OnImportsSatisfied 中执行初始化,并且部件应实现 IPartImportsSatisfiedNotification。

灵活运用部件的生命周期在具体使用MEF中会有很大得帮助,如:我们可能将WCF,EF做成组件,然后使用MEF整合这些组件,那么在组合成功后,我们可能需要读取WCF配置发布服务,或者读取DB.config建立数据库连接等。这时在OnImportsSatisfied 中完成这些操作可能效果更好。

http://www.cnblogs.com/pszw/archive/2011/12/14/2286895.html

创建策略(Creation Policy )和生命周期(Life Cycle)的更多相关文章

  1. @Scope注解设置创建bean的方式和生命周期

    1.1.1            Scope注解创建bean的方式和生命周期 作用 Scope设置对象在spring容器(IOC容器)中的生命周期,也可以理解为对象在spring容器中的创建方式. 取 ...

  2. iOS开发之控制器创建与加载(生命周期)

    1.如何创建一个控制器 控制器常见的创建方式有以下几种: (1)通过storyboard创建 (2)直接创建 MJViewController *mj = [[MJViewController all ...

  3. Maven(二)Maven项目的创建(命令、myeclipse)及生命周期

    上一篇给大家介绍了Maven的概念和仓库的一些信息,接下来给大家分享一下使用命令和MyEclipse创建Maven项目 一.使用命令管理Maven项目 1.1.创建Maven java项目 1)创建一 ...

  4. Vue项目的创建、路由、及生命周期钩子

    目录 一.Vue项目搭建 1.环境搭建 2.项目的创建 3.pycharm配置并启动vue项目 4.vue项目目录结构分析 5.Vue根据配置重新构建依赖 二.Vue项目创建时发生了什么 三.项目初始 ...

  5. 启动独立的tomcat服务器,没有自动创建ServletContext,对Context生命周期的监听失败

    1.可能web.xml文件里对ContextListener没有进行配置 2.web.xml文件有关对ContextListener的配置,出现了错误的单词拼写问题 比如 <listener&g ...

  6. web forms page和control的生命周期life cycle交互,以及page生命周期中每个event中需要做什么事情

    只有 page_load和page_init这些可以autoeventwireup RenderControl只提供override public override void RenderContro ...

  7. 这么简单的ES索引生命周期管理,不了解一下吗~

    对于日志或指标(metric)类时序性强的ES索引,因为数据量大,并且写入和查询大多都是近期时间内的数据.我们可以采用hot-warm-cold架构将索引数据切分成hot/warm/cold的索引.h ...

  8. Elasticsearch索引生命周期管理方案

    一.前言 在 Elasticsearch 的日常中,有很多如存储 系统日志.行为数据等方面的应用场景,这些场景的特点是数据量非常大,并且随着时间的增长 索引 的数量也会持续增长,然而这些场景基本上只有 ...

  9. Logstash & 索引生命周期管理(ILM)

    Grok语法 Grok是通过模式匹配的方式来识别日志中的数据,可以把Grok插件简单理解为升级版本的正则表达式.它拥有更多的模式,默认,Logstash拥有120个模式.如果这些模式不满足我们解析日志 ...

随机推荐

  1. 【2017 北京集训 String 改编版】子串

    题意 你有一个字符串,你需要支持两种操作: 1:在字符串的末尾插入一个字符 \(c\) 2:询问当前字符串的 \([l,r]\) 子串中的不同子串个数 为了加大难度,操作会被加密(强制在线). \(n ...

  2. H5 2次重定向301

    测试环境http ,生产https,导致请求重定向.加之H5自己的一次请求重定向,一共2次.

  3. DevExpress ASP.NET v19.1版本亮点:发布全新的Gantt控件

    行业领先的.NET界面控件DevExpress 发布了v19.1版本,本文将以系列文章的方式为大家介绍DevExpress ASP.NET Controls v19.1中新增的一些控件及增强的控件功能 ...

  4. Observer-Proxy拦截器 -ES6

    在目标对象前嫁接了一个拦截层,外界对该对象的访问都必须通过这层拦截 可实现观察者模式

  5. mybatis 关联查询和嵌套查询的简单示例

    两个表: Customer 顾客表 create table if not exists customer( customer_id int primary key auto_increment, f ...

  6. LVS+Heartbeat安装部署文档

    LVS+Heartbeat安装部署文档 发表回复 所需软件: ipvsadm-1.24-10.x86_64.rpmheartbeat-2.1.3-3.el5.centos.x86_64.rpmhear ...

  7. 【51nod1220】约数之和

    题目 d(k)表示k的所有约数的和.d(6) = 1 + 2 + 3 + 6 = 12. 定义S(N) = ∑1<=i<=N ∑1<=j<=N d(i*j). 例如:S(3) ...

  8. 3、Grid、GridSplitter 网格分离器、SharedSizeGroup 共享尺寸组

    Grid——网格布局,是WPF中最强大的布局容器,可以实现任何其他容器的布局.一个网格中只展示一个元素,若要展示多元素,可用容器 布局舍入:网格的边界有时会模糊,如三等分100宽度无法被整除.推荐设定 ...

  9. 在百度ueditor上粘贴从word中copy的图片和文字 图片无法显示的问题

    我这边从world 里面复制粘贴图片到编辑器中,它自动给我上传了,但是我是用的第三方的要设置一个token值,我找了很久,也没有找到应该在哪里设置这个上传的参数,如果是点击图片上传,我知道在dialo ...

  10. 51 Nod 1627瞬间移动(插板法!)

    1627 瞬间移动  基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题  收藏  关注 有一个无限大的矩形,初始时你在左上角(即第一行第一列),每次你都可以选择一个右 ...