MEF笔记 之延迟加载
文章参考:在MEF中实现延迟加载部件 作者:TianFang
仅有一个服务提供者时候
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting; namespace 延迟加载
{
interface ILogger
{
void Log(string message);
}
[Export(typeof(ILogger))]
class ConsoleLogger : ILogger
{
public void Log(string message)
{ Console.WriteLine("logger 1" + message);
}
}
class Host
{
[Import]
//延迟加载
Lazy<ILogger> _logger;
//非延迟加载
//ILogger _logger;
public Host()
{
var catalog = new AssemblyCatalog(this.GetType().Assembly);
var container = new CompositionContainer(catalog); //如果不是延迟加载的话这儿会创建ConsoleLogger对象
container.ComposeParts(this);
//非延迟加载
//_logger.Log("logworld");
//延迟加载
_logger.Value.Log("hello world"); }
}
}
当某一组件并不是立刻需要使用,或者内存开销很大。影响程序加载的速度。比如当程序启动的时候。这个时候我们可以使用延迟加载,也就是只有当程序用到的时候才会去加载该部件。我们可以使用Lazy<T>来标记导入的类型。这样就简单的实现了延迟加载。
注意如果使用Lazy<T>来标记对象类型的话,需要通该实例的Value属性调用实例方法 _logger.Value.Log("hello world");
如果是非延迟加载

如果延迟加载:

当有多个服务提供者的时候
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.Linq;
namespace 延迟加载
{
interface ILogger
{
void Log(string message);
}
[Export(typeof(ILogger))]
class ConsoleLogger : ILogger
{
public void Log(string message)
{
Console.WriteLine("ConsoleLogger " + message);
}
} [Export(typeof(ILogger))]
class DbLogger : ILogger
{
public void Log(string message)
{
Console.WriteLine("DbLogger " + message);
}
} class Host
{ //非延迟加载
//[ImportMany]
//ILogger[] _logger = null;
//延迟加载
[ImportMany]
Lazy<ILogger>[] _Lazylogger = null;
public Host()
{
var catalog = new AssemblyCatalog(this.GetType().Assembly);
var container = new CompositionContainer(catalog);
//非延迟加载此时会创建所有对象
container.ComposeParts(this);
//非延迟加载
//_logger.FirstOrDefault(i => i is DbLogger).Log("hello world");
//延迟加载,当调用的时候才创建对象,
//但是因为这儿有一个遍历,所以当调用一个对象的时候就会创建所以对象
_Lazylogger.FirstOrDefault(i => i.Value is DbLogger).Value.Log("DbLogger");
}
}
}
此时可以用ImportMany标记导入,同时用Lazy<T>包装我们的导入类型。但是此时有个问题,就是当我们如果通过类型遍历多个对象寻找可用导入时候,会创建所有对象。所以此时我们可以用元数据来判断是否使我们需要的导入。
通过元数据匹配需要的导入
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.Linq;
namespace 延迟加载
{
interface ILogger
{
void Log(string message);
}
//通过标记元数据来标记导出服务
[ExportMetadata("Name", "Console Logger")]
[Export(typeof(ILogger))]
class ConsoleLogger : ILogger
{
public void Log(string message)
{
Console.WriteLine("ConsoleLogger " + message);
}
}
//通过标记元数据来标记导出服务
[ExportMetadata("Name", "DbLogger")]
[Export(typeof(ILogger))]
class DbLogger : ILogger
{
public void Log(string message)
{
Console.WriteLine("DbLogger " + message);
}
}
public interface ILoggerData
{
string Name { get; }
}
class Host
{
//延迟加载
[ImportMany]
Lazy<ILogger,ILoggerData>[] _Lazylogger = null;
public Host()
{
var catalog = new AssemblyCatalog(this.GetType().Assembly);
var container = new CompositionContainer(catalog);
//非延迟加载此时会创建所有对象
container.ComposeParts(this);
//延迟加载,当调用的时候才创建对象,
//但是因为这儿有一个遍历,所以当调用一个对象的时候就会创建所以对象
//_Lazylogger.FirstOrDefault(i => i.Value is DbLogger).Value.Log("DbLogger");
_Lazylogger.FirstOrDefault(i => i.Metadata.Name == "DbLogger").Value.Log("DbLogger"); }
}
}

通过元数据可以匹配我们需要的导出服务。但是,通过单纯的标记 [ExportMetadata("Name", "DbLogger")]很麻烦,而且属性笔记多的时候代码也不整洁。对此我们可以封装一个元数据特性
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.Linq;
namespace 延迟加载
{
interface ILogger
{
void Log(string message);
}
//通过标记元数据来标记导出服务
[LoggerData("Console Logger")]
[Export(typeof(ILogger))]
class ConsoleLogger : ILogger
{
public void Log(string message)
{
Console.WriteLine("ConsoleLogger " + message);
}
}
//通过标记元数据来标记导出服务
[LoggerData("DbLogger")]
[Export(typeof(ILogger))]
class DbLogger : ILogger
{
public void Log(string message)
{
Console.WriteLine("DbLogger " + message);
}
}
public interface ILoggerData
{
string Name { get; }
}
[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
class LoggerDataAttribute : Attribute, ILoggerData
{
public string Name { get; private set; } public LoggerDataAttribute(string name)
{
this.Name = name;
}
}
class Host
{
//延迟加载
[ImportMany]
Lazy<ILogger, ILoggerData>[] _Lazylogger = null;
public Host()
{
var catalog = new AssemblyCatalog(this.GetType().Assembly);
var container = new CompositionContainer(catalog);
//非延迟加载此时会创建所有对象
container.ComposeParts(this);
//延迟加载,当调用的时候才创建对象,
//但是因为这儿有一个遍历,所以当调用一个对象的时候就会创建所以对象
//_Lazylogger.FirstOrDefault(i => i.Value is DbLogger).Value.Log("DbLogger");
_Lazylogger.FirstOrDefault(i => i.Metadata.Name == "DbLogger").Value.Log("DbLogger"); }
}
}
本文地址:http://www.cnblogs.com/santian/p/4357324.html
博客地址:http://www.cnblogs.com/santian/
MEF笔记 之延迟加载的更多相关文章
- 在MEF中实现延迟加载部件(转)
在MEF的宿主中,当我们通过Import声明导入的对象时,组装(Compose)的时候会创建该对象.例如: interface ILogger { void Log(string ...
- 在MEF中实现延迟加载部件
在MEF的宿主中,当我们通过Import声明导入的对象时,组装(Compose)的时候会创建该对象.例如: interface ILogger { void Log(string ...
- C#可扩展编程之MEF学习笔记(五):MEF高级进阶
好久没有写博客了,今天抽空继续写MEF系列的文章.有园友提出这种系列的文章要做个目录,看起来方便,所以就抽空做了一个,放到每篇文章的最后. 前面四篇讲了MEF的基础知识,学完了前四篇,MEF中比较常用 ...
- MEF的学习笔记
为什么要使用MEF 在商业应用软件开发过程中,对于各个软件项目,都需要建立相应的系统框架,为了更好的规范系统的开发,提高生产效率,应该在公司级别制定相应的API标准.这些API标准将站在系统架构层次, ...
- C#可扩展编程之MEF学习笔记(四):见证奇迹的时刻
前面三篇讲了MEF的基础和基本到导入导出方法,下面就是见证MEF真正魅力所在的时刻.如果没有看过前面的文章,请到我的博客首页查看. 前面我们都是在一个项目中写了一个类来测试的,但实际开发中,我们往往要 ...
- C#可扩展编程之MEF学习笔记(三):导出类的方法和属性
前面说完了导入和导出的几种方法,如果大家细心的话会注意到前面我们导出的都是类,那么方法和属性能不能导出呢???答案是肯定的,下面就来说下MEF是如何导出方法和属性的. 还是前面的代码,第二篇中已经提供 ...
- C#可扩展编程之MEF学习笔记(二):MEF的导出(Export)和导入(Import)
上一篇学习完了MEF的基础知识,编写了一个简单的DEMO,接下来接着上篇的内容继续学习,如果没有看过上一篇的内容, 请阅读:http://www.cnblogs.com/yunfeifei/p/392 ...
- C#可扩展编程之MEF学习笔记(一):MEF简介及简单的Demo
在文章开始之前,首先简单介绍一下什么是MEF,MEF,全称Managed Extensibility Framework(托管可扩展框架).单从名字我们不难发现:MEF是专门致力于解决扩展性问题的框架 ...
- [MEF]第03篇 MEF延迟加载导出部件及元数据
一.演示概述此演示介绍了MEF的延迟加载及元数据相关的内容.在实际的设计开发中,存在着某些对象是不需要在系统运行或者附属对象初始化的时候进行实例化的,只需要在使用到它的时候才会进行实例化,这种方式就可 ...
随机推荐
- 电脑(台式机||笔记本)开机password忘记通用解决方法
方法:直接制作一个老毛桃装机版u盘启动盘 网址:老毛桃官网 步骤:依照网址的解说,将制作好的U盘插入到电脑的usb插口.执行Windows 登入password破解菜单,搜索password所在的盘符 ...
- Dell服务器Raid卡电池策略调整
DELL服务器的Riad卡都有可充电池的特性,这块可充电电池,在不使用时,也会有微弱的放电现象,当它的电量放电到低到一定程度时,Raid卡控制器就会对电池进行一次“放电”,将剩余的电量放掉,然后再进行 ...
- csharp 面向对象编程
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Shap ...
- Yii2系列教程:安装及Hello World
http://www.yiiframework.com/ 安装Yii2 打算从头开始,所以,连安装Yii2也稍微写一点吧.安装Yii2最好的方式就是使用composer: composer globa ...
- 字符串编码原理--PHP数组原理与高级应用
基础知识 1.有几种表达方式(查看手册)2.单引号和双引号的区别,双引号解析变量.\n,\t等,八进制与十六进制编码 内部存储方式 c语言中怎么表示字符串,结构体存储了字符指针和长度1.字符串可以用[ ...
- Java 关于容器集合等数据结构详情图解,一目了然
建议把图片下载下来保存之,网页展示不开... watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY3NtX3F6/font/5a6L5L2T/fontsize/ ...
- password技术应用设计实践-安全信息传输系统(SITS)(用Java实现DES、RSA、MD5算法)
本系统包含五个模块,注冊模块.登录模块.RSA算法模块.DES算法模块.MD5算法模块. 这五个模块每个实现不同的功能. 注冊模块实现将username和password写入文件里,登录模块则负责将其 ...
- hdu1863 畅通project(判定最小生成树)
畅通project Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total ...
- Maven入门学习
1 Maven的安装 maven下载路径:http://maven.apache.org/download.cgi 我是在win7上安装了,安装后在cmd输入 mvn -v: C:\Users\*** ...
- SVN环境搭建(2)
原文地址:http://www.penglig.com/post-73.html TortoiseSVN的使用. 首先打开VisualSVN Server Manager,如图: 可以在窗口的右边看到 ...