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

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介:
 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  =   " 张三 " ;
    }
}
 
   除此之外,迟延加载也是支持弱类型的元数据类型的,也可以对元数据进行过滤,这里就不做详细的介绍,有兴趣的朋友可以自己去研究研究。




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

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
相关文章
|
2月前
|
存储 JSON JavaScript
组件的创建,引用,样式隔离以及methods,data,properties和数据事件监听
详细介绍了微信小程序中组件的创建、引用(包括局部引用和全局引用)、样式隔离、组件的data、methods和properties,以及组件的数据监听器的使用方法和场景。
组件的创建,引用,样式隔离以及methods,data,properties和数据事件监听
|
3月前
|
数据库
优化数据加载策略:深入探讨Entity Framework Core中的懒加载与显式加载技术及其适用场景
【8月更文挑战第31天】在 Entity Framework Core(EF Core)中,数据加载策略直接影响应用性能。本文将介绍懒加载(Lazy Loading)和显式加载(Eager Loading)的概念及适用场景。懒加载在访问导航属性时才加载关联实体,可优化性能,但可能引发多次数据库查询;显式加载则一次性加载所有关联实体,减少查询次数但增加单次查询的数据量。了解这些策略有助于开发高性能应用。
39 0
|
6月前
|
存储 JSON 数据格式
Spartacus i18n Resource 的默认加载和 Lazy Load 两种方式的比较
Spartacus i18n Resource 的默认加载和 Lazy Load 两种方式的比较
|
JavaScript
【ES6】模块化语法(默认、按需导入import导出export的操作)
ES6模块化语法(默认、按需导入导出的操作)
【ES6】模块化语法(默认、按需导入import导出export的操作)
SAP Spartacus lazy load module 里包含了被其他 Component 静态引用的组件该怎么办
SAP Spartacus lazy load module 里包含了被其他 Component 静态引用的组件该怎么办
107 0
SAP Spartacus lazy load module 里包含了被其他 Component 静态引用的组件该怎么办
|
JavaScript 前端开发
SAP Spartacus module 延迟加载和正常加载的 chunk 内容差异
SAP Spartacus module 延迟加载和正常加载的 chunk 内容差异
SAP Spartacus module 延迟加载和正常加载的 chunk 内容差异
[重要!] SAP Spartacus加载网络请求的entity状态切换,统一在loader.reducer.ts里完成
[重要!] SAP Spartacus加载网络请求的entity状态切换,统一在loader.reducer.ts里完成
86 0
[重要!] SAP Spartacus加载网络请求的entity状态切换,统一在loader.reducer.ts里完成
|
存储 容器
SAP Spartacus table cell如何通过cxOutlet在运行时动态注入组件
SAP Spartacus table cell如何通过cxOutlet在运行时动态注入组件
SAP Spartacus table cell如何通过cxOutlet在运行时动态注入组件
SAP Spartacus Unit List树形数据的加载触发时机
SAP Spartacus Unit List树形数据的加载触发时机
SAP Spartacus Unit List树形数据的加载触发时机