当前位置: 首页 > news >正文

MEF程序设计指南八:部件生命周期(Parts Lifetime)托管

  MEF中的每一个可进行动态装配的导出部件都是具有生命周期的,在没有特别需求的情况下一般都没有对生命周期进行管理,而实际上MEF已为每一个部件进行了默认的生命周期管理,MEF的生命周期分为三种:Any、Shared及NonShared,被定义在System.ComponentModel.Composition.CreationPolicy枚举对象中。

<!--<br/ /><br/ />Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />http://www.CodeHighlighter.com/<br/ /><br/ />--> namespace System.ComponentModel.Composition
{
public enum CreationPolicy
{
Any
= 0 ,
Shared
= 1 ,
NonShared
= 2 ,
}
}

  Any表示可共享或不共享,部件的实例用MEF容器根据不同的请求需求自动控制;Shared表示共享部件,既Shared类型的插件部件可以在多个MEF组合容器中共用;其次是NonShared类型,表示不共享部件实例,每当有新的请求就会创建一个新的对象实例。在MEF中,通过PartCreationPolicyAttribute特性实现对部件的生命周期配置。

<!--<br/ /><br/ />Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />http://www.CodeHighlighter.com/<br/ /><br/ />--> public interface IBookService
{
string GetBookName();
}

[PartCreationPolicy(CreationPolicy.Any)]
[Export(
typeof (IBookService))]
public class MEFBookService:IBookService
{
public string GetBookName()
{
return " 《MEF程序设计指南》 " ;
}
}

[PartCreationPolicy(CreationPolicy.NonShared)]
[Export(
typeof (IBookService))]
public class ASPNETBookService:IBookService
{
public string GetBookName()
{
return " 《ASP.NET项目案例》 " ;
}
}

[PartCreationPolicy(CreationPolicy.Shared)]
[Export(
typeof (IBookService))]
public class SLBookService:IBookService
{
public string GetBookName()
{
return " 《Silverlight高级编程》 " ;
}
}

  如上示例代码分别演示了使用Any、Shared及NonShared类型的生命周期托管类型对不同的对象进行导出部件配置。接下来通过导入部件并加入生命周期托管筛选,详细应用如下代码块所示:

<!--<br/ /><br/ />Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />http://www.CodeHighlighter.com/<br/ /><br/ />--> public partial class MainPage:UserControl
{
[ImportMany(RequiredCreationPolicy
= CreationPolicy.Shared)]
public List < IBookService > Service{ get ; set ;}

public MainPage()
{
InitializeComponent();

CompositionInitializer.SatisfyImports(
this );
// 得到成功装配的部件总数为2,因为Any类型是可以共存于多个MEF容器的。
int count = Service.Count;
}
}

  表面上看去和上一篇指南中介绍的部件的筛选过滤功能非常相似,不同是的过滤筛选是通过自定义筛选策略实现,而这里是通过MEF生命周期范围托管来实现的。在实际的项目开发中需根据不同的应用场景确定具体的技术实现方案。

  除了容器部件的生命周期托管,我们也得考虑部件容器自身的生命周期,容器什么时候释放资源,时候时候释放其内部部件的资源占用等。为了提高系统的整体性能,MEF建议将每一个可导入部件实现IDisposable 接口,用于资源的占用处理,如果部件从MEF容器中移除那么所对应占用的资源也会自动的清理。这里需要注意一点,就是当组合容器被释放掉后迟延加载的操作就不能再继续工作了,会抛出System.ObjectDisposedException异常。

      

  如上图所示,MEF的容器是具有层次结构的,最高层级容器为程序直接应用级容器,可以通过以下的代码获取到。

<!--<br/ /><br/ />Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />http://www.CodeHighlighter.com/<br/ /><br/ />--> varcatalog = new AssemblyCatalog( typeof (MainPage).Assembly);
varcontainer
= new CompositionContainer(catalog);

  位于顶级容器之下的子容器,通常来说都是控制着一些可动态装配的部件对象,如同上一篇指南中介绍到使用过滤器筛选部件的应用案例,通过过滤表达式从顶级容器中进行筛选,得出了新的MEF容器child,child托管着根据条件过滤筛选出来的所有结果部件对象。详细代码如下:

<!--<br/ /><br/ />Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />http://www.CodeHighlighter.com/<br/ /><br/ />--> // 获取当前应用程序目录
varcatalog = new AssemblyCatalog( typeof (MainPage).Assembly);
// 将目录装载进MEF组合容器
varparent = new CompositionContainer(catalog);
// 通过元数据过滤筛选出元数据名称为"UC"值为"CC"的组合部件
varfilteredCat = new FilteredCatalog(catalog,
def
=> def.Metadata.ContainsKey( " UC " ) &&
def.Metadata[
" UC " ].ToString() == " CC " );
varchild
= new CompositionContainer(filteredCat,parent);
varcontrol
= child.GetExportedValue < UserControl > ();

MEF官方网站:http://mef.codeplex.com/

  推荐指南:MEF程序设计指南一:在应用程序中宿主MEF

       MEF程序设计指南二:Silverlight中使用CompositionInitializer宿主MEF

       MEF程序设计指南三:MEF中组合部件(Composable Parts)与契约(Contracts)的基本应用

       MEF程序设计指南四:使用MEF声明导出(Exports)与导入(Imports)

     MEF程序设计指南五:迟延(Lazy)加载导出部件(Export Part)与元数据(Metadata)

       MEF程序设计指南六:MEF中的目录服务(DeploymentCatalog)

MEF程序设计指南七:使用目录(Catalog)动态装载xap与目录筛选(Filtered Catalog)

相关文章:

  • U盘装机神器--Universal-USB-Installer
  • 网站的安全与稳定
  • SQL 随机函数 rand() celling,floor
  • 打造自己的EDM营销客户列表
  • Windows下如何关闭端口
  • 非常期待altera的cycloneV
  • 时间
  • 条件编译
  • 《你能行:微软精英的职场心里话》
  • MySQL 数据库性能优化之表结构优化
  • 什么是野指针?
  • hdu 1555 How many days? (模拟)
  • 编解码学习笔记(十一):Flash Video系列
  • PE文件结构及其加载机制(三)
  • 编解码学习笔记(十二):其他编解码
  • 【mysql】环境安装、服务启动、密码设置
  • Android系统模拟器绘制实现概述
  • Java IO学习笔记一
  • Java应用性能调优
  • java正则表式的使用
  • session共享问题解决方案
  • spring + angular 实现导出excel
  • 从零搭建Koa2 Server
  • 湖南卫视:中国白领因网络偷菜成当代最寂寞的人?
  • 简单数学运算程序(不定期更新)
  • 利用jquery编写加法运算验证码
  • 网络应用优化——时延与带宽
  • 策略 : 一文教你成为人工智能(AI)领域专家
  • 浅谈sql中的in与not in,exists与not exists的区别
  • ​​​​​​​​​​​​​​汽车网络信息安全分析方法论
  • !! 2.对十份论文和报告中的关于OpenCV和Android NDK开发的总结
  • #stm32整理(一)flash读写
  • $.ajax()参数及用法
  • (1)(1.19) TeraRanger One/EVO测距仪
  • (20)目标检测算法之YOLOv5计算预选框、详解anchor计算
  • (8)Linux使用C语言读取proc/stat等cpu使用数据
  • (C语言)字符分类函数
  • (poj1.2.1)1970(筛选法模拟)
  • (ros//EnvironmentVariables)ros环境变量
  • (WSI分类)WSI分类文献小综述 2024
  • (八)光盘的挂载与解挂、挂载CentOS镜像、rpm安装软件详细学习笔记
  • (附源码)springboot宠物医疗服务网站 毕业设计688413
  • (附源码)ssm高校运动会管理系统 毕业设计 020419
  • (附源码)计算机毕业设计SSM教师教学质量评价系统
  • (收藏)Git和Repo扫盲——如何取得Android源代码
  • (一)eclipse Dynamic web project 工程目录以及文件路径问题
  • (转)Sql Server 保留几位小数的两种做法
  • ***通过什么方式***网吧
  • .NET 中使用 TaskCompletionSource 作为线程同步互斥或异步操作的事件
  • .net利用SQLBulkCopy进行数据库之间的大批量数据传递
  • .net知识和学习方法系列(二十一)CLR-枚举
  • .project文件
  • @angular/cli项目构建--http(2)
  • @SuppressLint(NewApi)和@TargetApi()的区别
  • @软考考生,这份软考高分攻略你须知道