原文地址: http://www.cnblogs.com/xiaokang088/archive/2012/02/21/2361631.html

MEF 的精髓在于插件式开发,方便扩展。

例如,应用程序的日志输出到文本,后来想改为输出到数据库,按照传统的办法,需要替换项目,删除原有的引用,增加新的引用;如果使用MEF,直接用新的dll替换原来的dll,即可搞定,这就是MEF的魅力。

下面就用简单的例子来实现上述的需求。

1. 建立一个解决方案,然后增加如下的几个项目

DBlog 输出日志到数据库的实现

TextLog 输出日志到文本的实现

ILog 输出日志的接口,调用方和实现者的中间桥梁

MEFConsoleHost 控制台应用程序,模拟实用场合

MEFWPFHost WPF 应用程序,模拟实用场合

2. 先定义接口ILog,非常简单,就一个方法

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace ILog
{
public interface ILogService
{
void Log(string content);
}
}

3. 输出到文本的实现TextLog

首先添加引用:引用刚才添加的接口Ilog 和System.ComponentModel.Composition

然后增加类TextLogService.cs,继承接口,并实现方法。

注意 类和方法都Public。

最后定义导出[Export(typeof(ILog.ILogService))]

这个是最主要的,和普通的类库区别也在这里

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.ComponentModel.Composition; namespace TextLog
{
[Export(typeof(ILog.ILogService))]
public class TextLogService : ILog.ILogService
{
public void Log(string content)
{
Console.WriteLine("TextLog:" + content); System.Diagnostics.TextWriterTraceListener TraceListener = new System.Diagnostics.TextWriterTraceListener(@"d:/debug.txt");
System.Diagnostics.Debug.Listeners.Add(TraceListener);
System.Diagnostics.Debug.Write(System.DateTime.Now.ToString()+" ");
Debug.Write("TextLog:" + content);
Debug.WriteLine("~~");
TraceListener.Flush();
}
}
}

4. 输出到数据库的实现DBLog,实现方法同上例,输出日志的时候区分一下。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.ComponentModel.Composition; namespace DBLog
{
[Export(typeof(ILog.ILogService))]
public class DBLogService: ILog.ILogService
{
public void Log(string content)
{
Console.WriteLine("DBLog:" + content); System.Diagnostics.TextWriterTraceListener TraceListener = new System.Diagnostics.TextWriterTraceListener(@"d:/debug.txt");
System.Diagnostics.Debug.Listeners.Add(TraceListener);
System.Diagnostics.Debug.Write(System.DateTime.Now.ToString()+" ");
Debug.Write("DBLog:" + content);
Debug.WriteLine("");
TraceListener.Flush();
}
}
}

5. 调用方MEFConsoleHost, 这个也需要增加两个引用,

ILog 和System.ComponentModel.Composition

主程序代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting; namespace MEFConsoleHost
{
class Program
{
[Import(typeof(ILog.ILogService))]
public ILog.ILogService CurrentLogService { get; set; } static void Main(string[] args)
{
Program pro = new Program();
pro.run();
} private void run()
{
//var catalog = new DirectoryCatalog(AppDomain.CurrentDomain.BaseDirectory,"DbLog.dll");
var catalog = new DirectoryCatalog(AppDomain.CurrentDomain.BaseDirectory, "TextLog.dll"); var container = new CompositionContainer(catalog);
container.ComposeParts(this); CurrentLogService.Log("*MEF Log Test Pass*");
Console.Read();
}
}
}

注意两个地方

a. 导入声明

[Import(typeof(ILogService))]
public ILogService CurrentLogService { get; set; }

用接口来定义实例,然后增加导入声明,和导出的相互对应

b. 建立Catalog和Container

var catalog = new DirectoryCatalog(AppDomain.CurrentDomain.BaseDirectory, "TextLog.dll");
var container = new CompositionContainer(catalog);
container.ComposeParts(this);

6. 把所有项目的输出都指定到同一个目录,也就说让dll和exe在同一目录,运行控制台程序,输出

TextLog: MEF Log Test Pass

7.如果我们要输出到数据库,把上面的catalog那一句改成

var catalog = new DirectoryCatalog(AppDomain.CurrentDomain.BaseDirectory,"DBLog.dll");

如果不想这么麻烦,这个目录里面只放DBLog.dll 或者TextLog.dll ,然后把上面那句改为:

var catalog = new DirectoryCatalog(AppDomain.CurrentDomain.BaseDirectory);

照样可以用。

如果两个都在,还这么搞,那不行的,因为就定义了一个实例,同目录有两个dll。

MEF简单示例的更多相关文章

  1. Linux下的C Socket编程 -- server端的简单示例

    Linux下的C Socket编程(三) server端的简单示例 经过前面的client端的学习,我们已经知道了如何创建socket,所以接下来就是去绑定他到具体的一个端口上面去. 绑定socket ...

  2. C# 构建XML(简单示例)

    C# 构建XML的简单示例: var pars = new Dictionary<string, string> { {"url","https://www. ...

  3. 根据juery CSS点击一个标签弹出一个遮罩层的简单示例

    <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...

  4. ACEXML解析XML文件——简单示例程序

    掌握了ACMXML库解析XML文件的方法后,下面来实现一个比较完整的程序. 定义基本结构 xml文件格式如下 <?xml version="1.0"?> <roo ...

  5. demo工程的清单文件及activity中api代码简单示例

    第一步注册一个账户,并创建一个应用.获取app ID与 app Key. 第二步下载sdk 第三步新建工程,修改清单文件,导入相关的sdk文件及调用相应的api搞定. 3.1 修改清单文件,主要是加入 ...

  6. spring-servlet.xml简单示例

    spring-servlet.xml简单示例 某个项目中的spring-servlet.xml 记下来以后研究用 <!-- springMVC简单配置 --> <?xml versi ...

  7. SignalR 简单示例

    一.什么是 SignalR ASP.NET SignalR is a library for ASP.NET developers that simplifies the process of add ...

  8. Web API 简单示例

    一.RESTful和Web API Representational State Transfer (REST) is a software architecture style consisting ...

  9. XML引入多scheme文件约束简单示例

    XML引入多scheme文件约束简单示例,用company.xsd和department.xsd来约束company.xml: company.xsd <?xml version="1 ...

随机推荐

  1. 修饰符(static、final、abstract)第一篇

    三个修饰符: 一.static: 作用域: 1. 属性 1.1 静态属性不必要创建新对象,可直接用类调用 1.2 其值发生改变,则类中的值也会随之而变并延伸到其他对象中 例子: class Anima ...

  2. ZOJ 1202 Divide and Count

    原题链接 题目大意:某人手上有一大批钻石,他同时有一些盒子恰好放下这些钻石,每个盒子可以放一个或多个,问一共有几种方法. 解法:这其实是一道排列与组合计算题,主要是写出组合算法的代码,把计算公式转为程 ...

  3. java03实验截图

  4. linux ssh免密码登录设置

    ssh-keygen -t rsa 全部回车 生成密钥默认放在了/root/.shh中 打开它 cd /root/.ssh cp id_rsa.pub authorized_keys 免密码登录 现在 ...

  5. UserDefault的使用,保存小数据到本地-iOS

    //保持到本地数据 NSArray *array=@[@"234",@"sdfe"]; NSUserDefaults *userDefault=[NSUserD ...

  6. linux -redhat rpm 和zabbix和各种rpm包下载地址

    redhat ftp://ftp.redhat.com/pub/redhat/linux/enterprise/6Client/en/os/SRPMS/ zabbix https://sourcefo ...

  7. 如何使用投影看着备注分享自己的PPT

    1.  设置多屏幕 一般你的笔记本就是1,   投影是2 2. 设置幻灯片的放映方式 设置幻灯片显示于另外一个监视器  并勾选显示演示者视图 3.  点击放映 就会出现 左上角是ppt本身, 右上角是 ...

  8. unity, 由unity5.2.1升级到5.4.2物体变亮解法

    由unity5.2.1升级到5.4.2之后,使用standard shader的物体会变亮. 原因如图: 框中两项是5.4.2多出来的,如果把specular Highlights的勾选去掉,就跟以前 ...

  9. GridView中实现点击某行的任意位置就选中该行

    来源:http://auv2009.blog.163.com/blog/static/68858712200992731010670/ 在 GridView中增加一列:(该列是选择按钮,让其不显示) ...

  10. linux -samba

    yum install samba samba-client samba-swat samba-common-3.6.9-151.el6.x86_64 //主要提供samba服务器的设置文件与设置文件 ...