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 > ();
复制代码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值