浅谈可扩展性框架:MEF
之前在使用Prism框架时接触到了可扩展性框架MEF(Managed Extensibility Framework),体验到MEF带来的极大的便利性与可扩展性。
此篇将编写一个可组合的应用程序,帮助大家快速熟悉MEF并将其应用于实际项目中。
有关MEF中的名词含义及功能实现,请大家移步:火车票
介绍下将要编写的Demo程序(下图),使用winform开发。
- 通过组合操作,程序动态加载可用部件进行组合操作。
- 通过解体操作,程序卸载所加载的所有部件。

新建项目后需引用程序集:
System.ComponentModel.Composition
主程序的核心代码如下:
public partial class Form1 : Form, IPartImportsSatisfiedNotification
{
[ImportMany(AllowRecomposition = true)]
private IEnumerable<Lazy<IPlugin, IPluginMetadata>> plugins; private AggregateCatalog catalog;
private CompositionContainer container;
public Form1()
{
InitializeComponent();
if (catalog == null)
catalog = new AggregateCatalog();
this.container = new CompositionContainer(catalog);
this.container.ComposeParts(this);
} #region Implementation of IPartImportsSatisfiedNotification
public void OnImportsSatisfied()
{
flowLayoutPanel1.Controls.Clear();
if (plugins != null && plugins.Count() != )
{
plugins.ToList().ForEach((a) =>
{
Button btn = new Button();
btn.Cursor = System.Windows.Forms.Cursors.Hand;
btn.Width = ;
btn.Height = ;
btn.Text = a.Metadata.ThePluginName;
btn.Click += (d, b) => { a.Value.Run(); };
flowLayoutPanel1.Controls.Add(btn);
});
}
}
#endregion public void CompositionAction()
{
catalog.Catalogs.Add(new AssemblyCatalog(Assembly.GetExecutingAssembly()));
}
......
}
1. IPartImportsSatisfiedNotification接口 : 在组件导入完成后,调用该接口中的方法(OnImportsSatisfied)。
2. MEF中最常用目录有三种:程序集目录(AssemblyCatalog),文件目录(DirectoryCatalog),聚合目录(AggregateCatalog)
程序集目录(AssemblyCatalog): 顾名思义可以向目录中添加程序集已存在类型中寻找可用于导入的部件。
var catalog = new AssemblyCatalog(System.Reflection.Assembly.GetExecutingAssembly());
文件夹目录(DirectoryCatalog):从文件夹中寻找可用于导入的部件
var catalog = new DirectoryCatalog("Extensions");
聚合目录(AggregateCatalog):可以向聚合目录包含上述两种方式
var catalog = new AggregateCatalog(
new AssemblyCatalog(System.Reflection.Assembly.GetExecutingAssembly()),
new DirectoryCatalog("Extensions"));
3. CompositionContainer : 组合容器,管理部件的组合并提供了一系列用于创建部件实例扩展方法等,详细资料
4. 目录与容器的一般使用方法:
var catalog = new AggregateCatalog();
var container = new CompositionContainer(catalog);
container.ComposeParts(this);
5. 导入:ImportAttribute 与 ImportManyAttribute
用于以下三种用途:字段,属性,方法
[import]
private IData _data; [import]
public IData Data{set;get;} [import]
public Action ClickAction;
ImportManyAttribute : 通过组合容器将所有符合契约的导出进行填充 (真别扭,说白了就是导入多个)
[ImportMany]
private IEnumerable<IPlugin> plugins;
AllowRecomposition : 是否允许重组
AllowRecomposition = true : 比如在程序运行的过程中,动态向聚合目录中添加可导出的部件,可以引发重组操作
catalog.Catalogs.Add(new AssemblyCatalog(Assembly.GetExecutingAssembly()));
需要注意的是:DirectoryCatalog 不会引发重组操作,可通过Refresh方法指定重组的策略。
6. System.Lazy<T> : MEF提供延迟导入。
下面来看一下,插件式如何实现的:
[ExportPluginAttribute(typeof(IPlugin), ThePluginName = "TheFristPlugin")]
public class TheFristPlugin : IPlugin
{
public TheFristPlugin()
{
this.TheName = "TheFristPlugin";
}
#region Implementation of IPlugin public string TheName { get; set; } public void Run()
{
MessageBox.Show("TheFristPlugin");
} #endregion
}
1. 简单说一下:导入与导出之前的关系
一个基于MEF开发的可扩展的程序,在容器中必然有很多的导出(Export),而这些Export又是怎么样找到自己的归宿呢。
Export 与 Import 依靠一种契约,来确定对方是否是自己的兄弟,说白了就是接口,比如上述程序所定义的IPlugin接口
public interface IPlugin
{
void Run();
}
使用 ExportAttribute 特性导出:
[Export("count")]
public int count{ get{return ;} }
[Export(typeof(Action))]
public void SendMsg(){return;}
[Export]
public class Person{}
有一个需求,主程序要求插件必须要指定插件名称:
1. 在IPlugin接口中定义:Name字段
2. 使用元数据
3. 使用自定义导出特性(与第二种方案类似)
如何使用元数据?
1.定义元数据视图,此处视图使用接口类型
public interface IPluginMetadata
{
string ThePluginName { get; }
}
2. 导出部件时,使用ExportMetaData特性
[ExportMetadata("ThePluginName", "TheFivePlugin")]
[Export(typeof(mef.test.wform.Interface.IPlugin))]
public class TheFivePlugin : mef.test.wform.Interface.IPlugin
{
public void Run()
{
MessageBox.Show("TheFivePlugin");
}
}
3. 导入元数据
[ImportMany(AllowRecomposition = true)]
private IEnumerable<Lazy<IPlugin, IPluginMetadata>> plugins;
4. 访问元数据
Lazy<T,TMetadata>.Value.Metadata
结束
到此为止,MEF 基本内容已讲解结束,如果有遗漏也请博友留言指出。
文章中很多都是白话,非官方语言,怎么理解的就怎么写,如果有不妥之处,还望各位博友指出。
新年快乐
浅谈可扩展性框架:MEF的更多相关文章
- 手撸ORM浅谈ORM框架之基础篇
好奇害死猫 一直觉得ORM框架好用.功能强大集众多优点于一身,当然ORM并非完美无缺,任何事物优缺点并存!我曾一度认为以为使用了ORM框架根本不需要关注Sql语句如何执行的,更不用关心优化的问题!!! ...
- 手撸ORM浅谈ORM框架之Add篇
快速传送 手撸ORM浅谈ORM框架之基础篇 手撸ORM浅谈ORM框架之Add篇 手撸ORM浅谈ORM框架之Update篇 手撸ORM浅谈ORM框架之Delete篇 手撸ORM浅谈ORM框架之Query ...
- 手撸ORM浅谈ORM框架之Update篇
快速传送 手撸ORM浅谈ORM框架之基础篇 手撸ORM浅谈ORM框架之Add篇 手撸ORM浅谈ORM框架之Update篇 手撸ORM浅谈ORM框架之Delete篇 手撸ORM浅谈ORM框架之Query ...
- 手撸ORM浅谈ORM框架之Delete篇
快速传送 手撸ORM浅谈ORM框架之基础篇 手撸ORM浅谈ORM框架之Add篇 手撸ORM浅谈ORM框架之Update篇 手撸ORM浅谈ORM框架之Delete篇 手撸ORM浅谈ORM框架之Query ...
- 手撸ORM浅谈ORM框架之Query篇
快速传送 手撸ORM浅谈ORM框架之基础篇 手撸ORM浅谈ORM框架之Add篇 手撸ORM浅谈ORM框架之Update篇 手撸ORM浅谈ORM框架之Delete篇 手撸ORM浅谈ORM框架之Query ...
- 【SSH学习笔记】浅谈SSH框架
说在前面 本学期我们有一门课叫做Java EE,由陈老师所授,主要讲的就是Java EE 中的SSH框架. 由于陈老师授课风格以及自己的原因导致学了整整一学期不知道在讲什么,所以才有了自己重新学习总结 ...
- 浅谈angular框架
最近新接触了一个js框架angular,这个框架有着诸多特性,最为核心的是:MVVM.模块化.自动化双向数据绑定.语义化标签.依赖注入,以上这些全部都是属于angular特性,虽然说它的功能十分的强大 ...
- 13.Object-C--浅谈Foundation框架常用的结构体
------- android培训.iOS培训.期待与您交流! ---------- 昨天学习了Foundation框架中常用的结构体,下面我简单的总结一下,如果错误麻烦请留言指正,谢谢! Found ...
- 2014-07-29 浅谈MVC框架中Razor与ASPX视图引擎
今天是在吾索实习的第15天.随着准备工作的完善,我们小组将逐步开始手机端BBS的开发,而且我们将计划使用MVC框架进行该系统的开发.虽然我们对MVC框架并不是非常熟悉,或许这会降低我们开发该系统的效率 ...
随机推荐
- linux maven安装配置
1.Run the wget command from the dir you want to extract maven too. wget http://mirrors.cnnic.cn/apac ...
- ionic本质
ionic本质一开发工具,ionic项目目录里在大堆东西,一堆插件(plugins),还有一堆npm包(node_modules),其实都是骗人的-( ̄▽ ̄-)~ 什么nodejs,npm只是为了解决 ...
- tomcat 一个项目在本机和办公室以外电脑服务器上搭建出现乱码问题
插入数据库都是???乱码 页面浏览之前在本机插入的数据都是正常的 修改conf目录下的server.xml文件 转义字符集 为 GBK 或 UTF-8 utf-8 即 添加 URIEncoding= ...
- DIV+CSS
1.可以引入外部的样式:<link rel="stylesheet" type="text/css" href="外部的CSS文件路径&q ...
- UITableView使用的一些技巧
1.如果想自己在视图中加一条线,和UITableView的cell的分割线颜色粗细一样,那么可以: UIView *lineView = [[UIView alloc] initWithFrame:C ...
- 2016 - 1 - 24 NSURLSession (一)
一: NSURLSession简介 1.实施步骤 1.1 使用 NSURLSession对象 创建TASK ,然后执行TASK 2.TASK的类型: 二: NSURLSession的简单使用: - ( ...
- mysql-5.6.17-win32免安装版配置
下载mysql-5.6.17-win32:官网下载地址百度 解压到自定义目录,我这里演示的是D:\wamp\mysql\ 复制根目录下的my-default.ini,改名为my.ini,my. ...
- MySQL起航
以前学php的时候用过MySQL,但是都没有认真地学习,只会在php代码中用几条极其简单SQL语句,以为MySQL就这么点用法,当时还在嘲笑学长们为什么会觉得MySQL难学,真是太尴尬了.好在开了数据 ...
- reverse-XNUCA-babyfuscator
上一次线上赛的一道题目 链接:http://pan.baidu.com/s/1qY9ztKC 密码:xlr2 这是一道代码混淆的题目,因为当时还不知道angr这样一个软件,所以我就用了自己的一种思路 ...
- C#数据结构
数据结构是相互之间存在一种或多种特定关系的数据元素的集合.在任何问题中,数据元素之间都不是孤立的,而是存在着一定的关系,这种关系称为结构(Structure).根据数据元素之间关系的不同特性,通常有 ...