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”,其值为“李四”的元数据信息,并且还定义了一个用于承载元数据结构的结构,接下来就可以通过迟延加载导入,进行元数据的获取了。

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

    

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

 
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 = "张三";
    }
}

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

【转】MEF程序设计指南五:迟延(Lazy)加载导出部件(Export Part)与元数据(Metadata)的更多相关文章

  1. 《MEF程序设计指南》博文汇总

    <MEF程序设计指南>博文汇总 在MEF之前,人们已经提出了许多依赖注入框架来解决应用的扩展性问题,比如OSGI 实现以Spring 等等.在 Microsoft 的平台上,.NET Fr ...

  2. [zhuan]《MEF程序设计指南》博文汇总

    http://www.cnblogs.com/beniao/archive/2010/08/11/1797537.html 在MEF之前,人们已经提出了许多依赖注入框架来解决应用的扩展性问题,比如OS ...

  3. [转]《MEF程序设计指南》博文汇总

    在MEF之前,人们已经提出了许多依赖注入框架来解决应用的扩展性问题,比如OSGI 实现以Spring 等等.在 Microsoft 的平台上,.NET Framework 自身内部包含组件模型和 Sy ...

  4. [转]MEF程序设计指南

    <MEF程序设计指南>博文汇总 在MEF之前,人们已经提出了许多依赖注入框架来解决应用的扩展性问题,比如OSGI 实现以Spring 等等.在 Microsoft 的平台上,.NET Fr ...

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

    在MEF中,使用[System.ComponentModel.Composition.ExportAttribute]支持多种级别的导出部件配置,包括类.字段.属性以及方法级别的导出部件,通过查看Ex ...

  6. MEF程序设计指南

    ############################################################################################## ##### ...

  7. Hibernate -- lazy加载

    Hibernate -- lazy加载 hibernate类级别懒加载: lazy:true(默认) //类级别懒加载 //load方法 //class lazy属性 //默认值:true load获 ...

  8. FreeSql (二十五)延时加载

    FreeSql 支持导航属性延时加载,即当我们需要用到的时候才进行加载(读取),支持1对1.多对1.1对多.多对多关系的导航属性. 当我们希望浏览某条订单信息的时候,才显示其对应的订单详细记录时,我们 ...

  9. 【原创】从零开始搭建Electron+Vue+Webpack项目框架(五)预加载和Electron自动更新

    导航: (一)Electron跑起来(二)从零搭建Vue全家桶+webpack项目框架(三)Electron+Vue+Webpack,联合调试整个项目(四)Electron配置润色(五)预加载及自动更 ...

随机推荐

  1. 函数图 https://www.processon.com/mindmap/5b5077fae4b040415ae39c64

    ---恢复内容结束---

  2. django模板中自动加载static

    TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join( ...

  3. JAVA SpringMVC + FormDate + Vue + file表单 ( 实现 js 单文件和多文件上传 )

    JS 部分 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <tit ...

  4. Eclipse “cannot be resolved to a type”

    遇到这坑爹的问题,网上各种答案. 只有这个能解决我的问题,eclipse机制问题: Eclipse “cannot be resolved to a type”

  5. django celery 定时任务

    可参考上一篇:http://www.cnblogs.com/wumingxiaoyao/p/8515075.html 1. 安装 django-celery-beat pip3 install dja ...

  6. CentOS 7 firewalld

    1.firewalld的基本使用 启动: systemctl start firewalld 查看状态: systemctl status firewalld 停止: systemctl disabl ...

  7. 快速可靠网络传输协议 KCP(转)

    KCP 是一个快速可靠协议,能以比 TCP浪费10%-20%的带宽的代价,换取平均延迟降低30%-40%,且最大延迟降低三倍的传输效果.纯算法实现,并不负责底层协议(如UDP)的收发,需要使用者自己定 ...

  8. mongodb基础学习6-用户管理

    下面来说一下用户管理,前面对mongodb进行操作都无需用户名密码进行登陆,可以设置用户进行数据库的访问 添加用户:三个参数:用户名,密码,是否只读 开启权限验证 进行验证 修改密码 删除用户 用户角 ...

  9. 如何将String转换为int

    1. int i = Integer.parseInt([String]); 或 i = Integer.parseInt([String],[int radix]); Integer.parseIn ...

  10. apache commons pool

    apache commons下的pool 其中的borrowObject函数源代码显示其产生可用对象的过程: 如果stack中有空闲的对象,则pop对象,激活对象(activate函数),验证对象(v ...