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

  MEF中使用导出与导入,实质上就是对一个对象的实例化的过程,通过MEF的特性降低了对象的直接依赖,从而让系统的设计达到一种高灵活、高扩展性的效果。在具体的设计开发中,存在着某些对象是不需要在系统运行或者的附属对象初始化的时候进行实例化的,仅仅只需要在需要使用到他的时候才会进行实例化,从系统的上来说这也是提高系统性能的一种可行的实现方式,这种方式就可以理解为对象的迟延初始化,或者叫迟延加载。MEF也对此使用场景提供了完善的实现机制,下面来看看在MEF中的迟延初始化是如何使用的。

namespace  MEFTraining.LzayImports
{
    
public   interface  ILogger
    {
        
void  WriteLog( string  message);
    }

    [Export(
typeof (ILogger))]
    
public   class  DBLogger : ILogger
    {
        
public   void  WriteLog( string  message)
        {
            MessageBox.Show(message);
        }
    }
}

 

  通过使用前几篇博文中使用的日志组件为例,在日志记录的具体实现对象上进行对象的导出[Export]配置。如果是使用传统的方式进行部件的导入则如下代码块所示:

[Import( typeof (ILogger))]
public  ILogger Logger {  get set ; }

 

  如果需要进行迟延(Lazy)加载,MEF专门提供了用于迟延加载的方式,既使用Lazy类来完成迟延加载,然后通过其他属性Value获取到所加载到的对象。详细的使用如下代码块:

public   partial   class  MainPage : UserControl
{
    
// 传统加载
    [Import( typeof (ILogger))]
    
public  ILogger Logger {  get set ; }
    
    
// 迟延加载
    [Import]
    
public  Lazy < ILogger >  Service;

    
public  MainPage()
    {
        InitializeComponent();

        CompositionInitializer.SatisfyImports(
this );

        Logger.WriteLog(
" 日志内容 " );

        Service.Value.WriteLog(
" 日志内容 " );
    }
}

 

  通过调试输出可以得到使用迟延导入的对象的详细信息,下面是通过在命令窗口中输出的Service和Service.Value的详细信息。

Service
ThreadSafetyMode
= PublicationOnly, IsValueCreated = true , IsValueFaulted = false , Value = {MEFTraining.LzayImports.DBLogger}
    IsValueCreated: 
true
Service.Value
{MEFTraining.LzayImports.DBLogger}
    [MEFTraining.LzayImports.DBLogger]: {MEFTraining.LzayImports.DBLogger}

 

   迟延加载还支持元数据的导出和导入,主要使用[MetadataAttribute]特性实现,实际开发中可以进行自定义元数据结构,这里以一个空的元数据接口进行元数据的导入应用演示。

public   interface  IMetadata
{
      
}

 

  在导出部件中就可以使用元数据特性进行声明,如下简单的应用。

[MetadataAttribute]
[Export(
typeof (Users))]
public   class  Users
{
    
public   string  UserName  =   " 张三 " ;
}

 

  元数据的导入应用如下代码块所示:

public   partial   class  MetadataControl : UserControl
{
    [Import(
typeof (Users))]
    
public  Lazy < Users,IMetadata >  Users {  get set ; }

    
public  MetadataControl()
    {
        InitializeComponent();

        
// 宿主MEF托管扩展容器
        CompositionInitializer.SatisfyImports( this );

        MessageBox.Show(Users.Value.UserName);
    }
}

 

  对于的调试输出为下面代码块所示:

Users
ThreadSafetyMode
= PublicationOnly, IsValueCreated = true , IsValueFaulted = false Value = {MEFTraining.LzayImports.Users}
    
base  {System.Lazy < MEFTraining.LzayImports.Users > }: ThreadSafetyMode = PublicationOnly, IsValueCreated = true , IsValueFaulted = false , Value = {MEFTraining.LzayImports.Users}
    Metadata: {_proxy_MEFTraining.LzayImports.IMetadata_0174a468
- 9771 - 4271 - a37e - 9a4a83eca6bd}

 

  MEF中也提供了专门用于元数据导入、导出的特性[ExportMetadata],使用ExportMetadata基本可以满足大部分元数据的导出、导入支持。通过修改上面的示例来实现自定义元数据结构的导入、导出应用演示。

public   interface  IMetadata
{
    
string  Name {  get ; }
}

[ExportMetadata(
" Name " , " 李四 " )]
[Export(
typeof (Users))]
public   class  Users
{
    
public   string  UserName  =   " 张三 " ;
}

 

  上面的示例代码演示了通过元数据导出属性名为“Name”,其值为“李四”的元数据信息,并且还定义了一个用于承载元数据结构的结构,接下来就可以通过迟延加载导入,进行元数据的获取了。

public   partial   class  MetadataControl : UserControl
{
    [Import(
typeof (Users))]
    
public  Lazy < Users,IMetadata >  Users {  get set ; }

    
public  MetadataControl()
    {
        InitializeComponent();

        
// 宿主MEF托管扩展容器
        CompositionInitializer.SatisfyImports( this );

        MessageBox.Show(Users.Value.UserName);
    }
}

 

  下图为允许调试中的截图,可以很清楚的看到,在进行迟延导入的时候已经将导出部件中的元数据信息成功的导入到了当前对象实例属性中。

    

 

  下面是完整的元数据应用实例代码。

namespace  MEFTraining.LzayImports
{
    
public   partial   class  MetadataControl : UserControl
    {
        [Import(
typeof (Users))]
        
public  Lazy < Users,IMetadata >  Users {  get set ; }

        
public  MetadataControl()
        {
            InitializeComponent();

            
// 宿主MEF托管扩展容器
            CompositionInitializer.SatisfyImports( this );

            MessageBox.Show(Users.Value.UserName);
        }
    }

    
public   interface  IMetadata
    {
        
string  Name {  get ; }
    }

    [ExportMetadata(
" Name " , " 李四 " )]
    [Export(
typeof (Users))]
    
public   class  Users
    {
        
public   string  UserName  =   " 张三 " ;
    }
}

 

   除此之外,迟延加载也是支持弱类型的元数据类型的,也可以对元数据进行过滤,这里就不做详细的介绍,有兴趣的朋友可以自己去研究研究。

 

  

 

  本篇参考:Lazy Imports  、Exports and Metadata  

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

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

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

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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值