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

简介:
 MEF中的每一个可进行动态装配的导出部件都是具有生命周期的,在没有特别需求的情况下一般都没有对生命周期进行管理,而实际上MEF已为每一个部件进行了默认的生命周期管理,MEF的生命周期分为三种:Any、Shared及NonShared,被定义在System.ComponentModel.Composition.CreationPolicy枚举对象中。
namespace  System.ComponentModel.Composition
{
    
public   enum  CreationPolicy
    {
         Any 
=   0 ,
         Shared 
=   1 ,
         NonShared 
=   2 ,
    }
}
 
  Any表示可共享或不共享,部件的实例用MEF容器根据不同的请求需求自动控制;Shared表示共享部件,既Shared类型的插件部件可以在多个MEF组合容器中共用;其次是NonShared类型,表示不共享部件实例,每当有新的请求就会创建一个新的对象实例。在MEF中,通过PartCreationPolicyAttribute特性实现对部件的生命周期配置。
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类型的生命周期托管类型对不同的对象进行导出部件配置。接下来通过导入部件并加入生命周期托管筛选,详细应用如下代码块所示:
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的容器是具有层次结构的,最高层级容器为程序直接应用级容器,可以通过以下的代码获取到。
 
var catalog  =   new  AssemblyCatalog( typeof (MainPage).Assembly);
var container 
=   new  CompositionContainer(catalog);
 
 
  位于顶级容器之下的子容器,通常来说都是控制着一些可动态装配的部件对象,如同上一篇指南中介绍到使用过滤器筛选部件的应用案例,通过过滤表达式从顶级容器中进行筛选,得出了新的MEF容器child,child托管着根据条件过滤筛选出来的所有结果部件对象。详细代码如下:
// 获取当前应用程序目录
var catalog  =   new  AssemblyCatalog( typeof (MainPage).Assembly);
// 将目录装载进MEF组合容器
var parent  =   new  CompositionContainer(catalog);
// 通过元数据过滤筛选出元数据名称为"UC"值为"CC"的组合部件
var filteredCat  =   new  FilteredCatalog(catalog,
    def 
=>  def.Metadata.ContainsKey( " UC " &&
    def.Metadata[
" UC " ].ToString()  ==   " CC " );
var child 
=   new  CompositionContainer(filteredCat, parent);
var control 
=  child.GetExportedValue < UserControl > ();
 
 




本文转自 beniao 51CTO博客,原文链接:http://blog.51cto.com/beniao/362507,如需转载请自行联系原作者

目录
相关文章
|
2月前
|
iOS开发 开发者 UED
探索iOS开发中的SwiftUI框架:构建现代应用程序的桥梁
本文深入探讨了SwiftUI框架在iOS开发中的应用,揭示了其对提升开发效率和改善用户体验的重要性。通过分析SwiftUI的设计哲学、核心组件以及与旧有开发模式的比较,文章旨在为读者提供关于如何利用SwiftUI构建现代化应用程序的实用指南。
|
3月前
|
存储 图形学
【unity小技巧】unity事件系统创建通用的对象交互的功能
【unity小技巧】unity事件系统创建通用的对象交互的功能
39 0
|
4月前
|
编译器 异构计算 Windows
LabVIEWCompactRIO 开发指南27 创建模块化、可重复使用的子VI
LabVIEWCompactRIO 开发指南27 创建模块化、可重复使用的子VI
26 2
|
4月前
|
设计模式 前端开发 数据库
构建高效Android应用:使用Jetpack架构组件实现MVVM模式
【4月更文挑战第21天】 在移动开发领域,构建一个既健壮又易于维护的Android应用是每个开发者的目标。随着项目复杂度的增加,传统的MVP或MVC架构往往难以应对快速变化的市场需求和复杂的业务逻辑。本文将探讨如何利用Android Jetpack中的架构组件来实施MVVM(Model-View-ViewModel)设计模式,旨在提供一个更加模块化、可测试且易于管理的代码结构。通过具体案例分析,我们将展示如何使用LiveData, ViewModel, 和Repository来实现界面与业务逻辑的分离,以及如何利用Room数据库进行持久化存储。最终,你将获得一个响应迅速、可扩展且符合现代软件工
62 0
|
11月前
|
前端开发
ABAP2UI5 项目里动态创建模型的特性介绍
ABAP2UI5 项目里动态创建模型的特性介绍
|
12月前
|
API C# 数据安全/隐私保护
C#之二十一 创建MDI应用程序和组件开发
C#之二十一 创建MDI应用程序和组件开发
98 0
|
JavaScript 前端开发 API
ReactJS 101:构建可重用组件、管理状态和创建实际应用程序的初学者指南
ReactJS 101:构建可重用组件、管理状态和创建实际应用程序的初学者指南
142 0
|
iOS开发 容器
AppleWatch开发入门三——代码交互与控制器生命周期
AppleWatch开发入门三——代码交互与控制器生命周期
150 0
AppleWatch开发入门三——代码交互与控制器生命周期