博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
MEF TIP1:基础
阅读量:7250 次
发布时间:2019-06-29

本文共 2816 字,大约阅读时间需要 9 分钟。

1:MEF核心概念 

可组合的部件(或简称“Part”)— 一个部件向其他部件提供服务,或使用其他部件提供的服务。MEF 中的部件可来自任何位置(应用程序内部或外部);从 MEF 的角度来看,这并无区别。 
导出 — 导出是部件提供的服务。某个部件提供一个导出时,称为该部件导出 该服务。 
导入 — 导入是部件使用的服务。某个部件使用一个导入时,称为该部件导入 该服务。 
约定 — 约定是导出或导入的标识符。导出程序指定其提供的字符串约定,导入程序指定其需要的约定。MEF 从要导出和导入的类型派生约定名称,因此在大多数情况下,您不必考虑这一点。 
组合 — 部件由 MEF 组合,MEF 将部件实例化,然后使导出程序与导入程序相匹配。

简短说一下MEF的工作原理,MEF的核心包括一个catalog和一个CompositionContainer。category用于发现扩展,而container用于协调创建和梳理依赖性。每个可组合的Part提供了一个或多个Export,并且通常依赖于一个或多个外部提供的服务或 Import。

2:一个最简单的例子

using 
System;
using 
System.Collections.Generic;
using 
System.Linq;
using 
System.Text;
using 
System.ComponentModel.Composition;
using 
System.ComponentModel.Composition.Hosting;
using 
System.Reflection;
 
namespace 
ConsoleApplication2
{
    
public 
class 
Program
    
{
        
[Import]
        
public 
IMessageSender MessageSender {
get
;
set
; }
 
        
public 
static 
void 
Main(
string
[] args)
        
{
            
Program p =
new 
Program();
            
p.Run();
        
}
 
        
public 
void 
Run()
        
{
            
Compose();
            
MessageSender.Send(
"Message Sent"
);
        
}
 
        
private 
void 
Compose()
        
{
            
AssemblyCatalog catalog =
new 
AssemblyCatalog(Assembly.GetExecutingAssembly());
            
var 
container =
new 
CompositionContainer(catalog);
            
container.ComposeParts(
this
);
        
}
    
}
 
    
public 
interface 
IMessageSender
    
{
        
void 
Send(
string 
message);
    
}
 
    
[Export(
typeof
(IMessageSender))]
    
public 
class 
EmailSender : IMessageSender
    
{
        
public 
void 
Send(
string 
message)
        
{
            
Console.WriteLine(message);
        
}
    
}
 
    
}

上面的代码在运行时,MessageSender会被自动组合到EmailSender实例对象。光从以上代码我们可能会觉得毫无意义,我们可以试着将接口和实现封装到不同的项目中,MEF的威力便体现出来了。

3:MEF的意义

接口和实现独立出去的例子如下:

主项目只和接口项目相关,其中代码修改为:

public 
class 
Program
{
    
[Import]
    
public 
IMessageSender MessageSender {
get
;
set
; }
 
    
public 
static 
void 
Main(
string
[] args)
    
{
        
Program p =
new 
Program();
        
p.Run();
    
}
 
    
public 
void 
Run()
    
{
        
Compose();
        
MessageSender.Send(
"Message Sent"
);
    
}
 
    
private 
void 
Compose()
    
{
        
var 
catalog =
new 
DirectoryCatalog(
@".\"
);
        
var 
container =
new 
CompositionContainer(catalog);
        
container.ComposeParts(
this
);
    
}
}

运行程序,可以发现和上面的那个最简单的例子的结果是一致的。但是我们这个时候可以随意扩展实现,也即替换掉Service1,随意实现我们的Service2,Service3……。

4:同时组合多个项目

我们可以实现一个Service2,假设该项目存在实现:

[Export(
typeof
(IMessageSender))]
public 
class 
TCPSender : IMessageSender
{
    
public 
void 
Send(
string 
message)
    
{
        
Console.WriteLine(
"TCPSender:" 
+ message);
    
}
}

这个时候,主程序修改为,注意其中的属性变成了ImportMany,代码如下:

public 
class 
Program
{
    
[ImportMany]
    
public 
IEnumerable<IMessageSender> Senders {
get
;
set
; }
 
    
public 
void 
Notify(
string 
message)
    
{
        
foreach 
(IMessageSender sender
in 
Senders)
            
sender.Send(message);
    
}
 
    
public 
static 
void 
Main(
string
[] args)
    
{
        
Program p =
new 
Program();
        
p.Run();
    
}
 
    
public 
void 
Run()
    
{
        
Compose();
        
Notify(
"Message Sent"
);
    
}
 
    
private 
void 
Compose()
    
{
        
var 
catalog =
new 
DirectoryCatalog(
@".\"
);
        
var 
container =
new 
CompositionContainer(catalog);
        
container.ComposeParts(
this
);
    
}
}

程序运行输出为:

本文转自最课程陆敏技博客园博客,原文链接:http://www.cnblogs.com/luminji/archive/2011/08/16/2137490.html,如需转载请自行联系原作者

你可能感兴趣的文章
JS中的类型检测总结
查看>>
vue小demo0
查看>>
QQ邮箱无法收到系统邮件的问题处理
查看>>
iPhone X 网页导航概念
查看>>
python脚本监控程序问题&解决
查看>>
C++ 入门教程(开发文档)
查看>>
UCloud可支撑单可用区320,000服务器的数据中心网络系统设计
查看>>
测试网络rinkeby外文资料
查看>>
php 非常有用的高级函数PATH_SEPARATOR常量和set_include_path
查看>>
android studio 3.0 入坑需知
查看>>
java线程--打印错误堆栈信息
查看>>
你都用过世界地图中哪些数据中心
查看>>
QuickBI助你成为分析师-保证数据安全:行级权限
查看>>
记录安全扫描后进行的代码重构各类问题以及处理办法
查看>>
三周第一次课
查看>>
解决手机运行appium会自动安装settingapp和unlock
查看>>
SAP S/4HANA CDS View的访问控制实现:DCL介绍
查看>>
快速了解掌握中文自然语言处理
查看>>
omni core api速查表
查看>>
比特币 的 正统 ——BCH
查看>>