(3)MEF插件系统中通信机制的设计和实现

文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/

1.背景

一般的WinForm中通过C#自带的Event机制便能很好的实现事件的注册和分发,但是,在插件系统中却不能这么简单的直接用已有的类来完成。一个插件本不包含另外一个插件,它们均是独立解耦的,实现插件和插件间的通信还需要我们设计出一个事件引擎来完成这个需求。

目前很多高级语言中基本都实现了观察者模式,并进行了自己的包装。比如C#中的delegate和event组合,java awt中的Event和addActionListener组合,Flex中的Event、addEventListener、dispatchEvent等。

不过这里如果要实现插件系统的事件机制,需要重新自己利用观察者模式来进行设计。而且还将涉及到泛型这个概念。

2.知识准备

2.1观察者模式

这里先给出观察者模式的UML图:

 

可以把观察者模式理解为两个部分:

(1)Obesrver(观察者):每个观察者均有自己的行为方式,但是他们均继承于同一个基类,此基类中定义了一个所有继承观察者均有的行为触发方法。

(2)Subject(触发者):触发者即是被观察者,在Subject中一定会有一个容器来存储与触发者相关的观察者,因为包含观察者容器,所以Subject方法中提供了注册和注销的方法。同时Subject中一定有一个触发方法,当调用此方法时,便会遍历装有观察者的容器,Obeserver类再利用多态特性实现了每个观察者特有的行为。

2.2. 泛型

泛型是具有占位符(类型参数)的类、结构、接口和方法,这些占位符是类、结构、接口和方法所存储或使用的一个或多个类型的占位符。

事件机制中的通信数据因为不能确定为某种具体数据,在实现中,统一用泛型来代替。

3.以一个需求为线索

项目中需要在插件处理完影像后,将处理完的影像的地址、名称以及类型通知给宿主。然后宿主根据得到的消息和数据,将处理完后的影像展现出来。

4.设计完整的可导出的触发者(Subject)部分

这部分设计的UML图如下所示:

 

4.1设计单个触发者(Subject)

 

代码中实现了观察者容器、注入和发布部分。

4.2 设计要传递的内容(data)

我的项目中需要将插件处理完影像后,将处理完的影像的地址、名称以及类型通知给宿主。于是我将这样设计我的事件中包含的数据:

 

4.3 设计触发者子类(ConcreteSubject)

具体的要传递的数据是对应具体的触发者的。我们可以有多种多样的事件,而每种触发者将对应一种事件,所以这里需要设计多个触发者子类。针对3.1.2中说的插件处理完影像后的触发事件,这里给出实现的代码:

 

4.4 设计MEF中的契约(Contract)

 

4.5 设计触发者容器(EventAggregator)

 

触发者容器中包含了所有的触发者,并且提供了获取容器中具体触发者的方法,即GetEvent方法。代码中还给出了Export标签,这是为了让其他插件和组件加载后能够将触发者容器注入其中。这样需要将某个方法注入到一个具体的事件上时,则只需在触发者容器中通过GetEvent方法得到该触发者,然后将方法再subscribe到这个触发者中。

4.6整体结构

 

5. 设计完整的可注入的观察者(Observer)部分

5.1将触发者容器(EventAggregator)注入

 

5.2 将Observer注册到对应的触发者(Subject)中

首先获得需要注册入的ConcreteSubject,然后将Observer注入其中,这里的Observer是继承于Action的。

 

6.设计事件触发(invoke)部分

6.1将触发者容器(EventAggregator)注入

这里同样需要将EventAggregator注入到事件被触发的模块中。

 

6.2 触发机制的实现

 

首先获得需要触发的触发者(ConcreteSubject),然后将需要传递的信息实例化,最后触发这个事件(Publish)。

7.总结

到这里,我已经把我的MEF插件系统中的事件机制解析完了。其实说到底就是一个观察者模式的实现,只是在这个模式的基础上做了一个包装。在下一节中,我将主要讲解MEF插件中插件注入到宿主中的过程,和插件在宿主中界面的实现。

                                                      -----欢迎转载,但保留版权,请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/

                                                             如果您觉得本文确实帮助了您,可以微信扫一扫,进行小额的打赏和鼓励,谢谢 ^_^

                                

时间: 2024-08-01 20:32:49

(3)MEF插件系统中通信机制的设计和实现的相关文章

社交网络中刺激机制的设计

社交网络不同于普通的基础网络,是建立在真实人际关系基础上的,对网络的结构特点进行研究对于进一步推动网络的发展具有非常重要的意义,结构研究既包括简单的基础构造研究,例如网络规模,节点可达性,节点之间距离的衡量等等,也包括异常复杂的特殊结构研究,主要包括度数中心性(Degree Centrality),亲近中心性(Closeness Centrality)和中介中心性(Between's centrality)等等.美国不少学者关注于网络中节点所处位置的重要性,以及节点的聚集性,互惠作用等相关方面的

IM系统中聊天记录模块的设计与实现

看到很多开发IM系统的朋友都想实现聊天记录存储和查询这一不可或缺的功能,这里我就把自己前段时间为傲瑞通(OrayTalk)开发聊天记录模块的经验分享出来,供需要的朋友参考下. 一.总体设计 1.存储位置 从一开始我们就打算在服务端和客户端本地同时存储聊天记录,而且,在客户端查看聊天记录时,可以选择是从本地加载.还是从服务器加载.这样做的好处有两个: (1)从本地加载聊天记录速度非常快. (2)当更换了登录的机器,在任何地方任何时刻都可以从服务器加载完整的聊天记录,记录永远不会丢失. 2.存储方案

大规模定制企业CRM系统中数据仓库的应用设计

一.大规模定制客户智能http://www.aliyun.com/zixun/aggregation/8302.html">数据仓库技术 1.数据的抽取.由于数据仓库是一个独立的数据环境,它需要通过抽取过程将数据从联机事务处理系统.外部数据源.脱机的数据存储介质中导入到数据仓库.数据抽取在技术上主要涉及互连.复制.增量,转换.调度和监控等几个方面. 2.数据的存储和管理.数据仓库遇到的第一个问题是对大量数据的存储和管理.这里所涉及的数据量比传统事务处理大得多且随时间的推移而累积.数据仓库的

.NET插件系统之二——不实例化获取插件信息和可视化方法

 面临的问题       在开发插件系统中,我们通常会面临这样的问题:        一些功能并不是在开启时就要被使用的,例如VS中的大量功能对一个大部分程序员来说用不着,但框架本身却应该向用户提供该插件的相应信息?        在可视化的插件功能列表中,我们不仅希望提供简单的插件名称信息,更希望能以图片,或动画等形式展示其功能特性,便于用户选择.        插入辅助类来解决上一个问题? 想法虽好,但破坏了"插件"的精髓,它应该是独立可插拔的,如果存在其之外的辅助类,那真是得不偿

.NET实现之自己动手写高内聚插件系统

今天跟大家分享一下本人在.NET简谈构件系统开发模式一文中提到的软件架构设计思路的具体实现细节. 大家看了我这篇文章后,总问我为什么要起个这么怪异的名字构件而不用插件.其实这个名字在我脑子漂浮了很久,一直找不到合适的场合用它. 在一本书上是这样解释构件的:构件是可以更换的部件,并且这个部件是由一系列很小的部件组成,同样这些小的部件由更小的部件组成:我为什么要区分插件与构件主要原因是这两个名字所表达的思想不同.插件是可插.可卸的过程,没有强调无限极的递归实现子插件的意思,所以本人将其区分开来:当然

.NET实现之(自己动手写高内聚插件系统)

今天跟大家分享一下本人在".NET简谈构件系统开发模式"一文中提到的软件架构设计思路的具体实现细节. 大家看了我这篇文章后,总问我为什么要起个这么怪异的名字"构件"而不用"插件".其实这个名字在我脑子漂浮了很久,一直找不到合适的场合用它. 在一本书上是这样解释构件的:构件是可以更换的部件,并且这个部件是由一系列很小的部件组成,同样这些小的部件由更小的部件组成:我为什么要区分插件与构件主要原因是这两个名字所表达的思想不同.插件是可插.可卸的过程,没

MongoDB在呼叫中心系统中的应用

MongoDB在呼叫中心系统中的应用 席晓筱,詹舒波 MongoDB是一个可扩展,高性能,无模式,基于文档存储的非关系型数据管理系统.它的面向文档存储的特点使得MongoDB可以支持松散结构数据的存储:弱一致性特点使得MongoDB可以保证更快速的用户访问速度:高性能特点使得MongoDB可以更好的支持大数据量的处理.呼叫中心的不断发展对数据存储系统提出了新要求:大数据量+松散数据结构+高访问速度,因此引入非关系数据库MongoDB作为呼叫中心部分应用数据的存储系统十分合适.本文首先对Mongo

浅谈C#中一种类插件系统编写的简单方法(插件间、插件宿主间本身不需要通信)

文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/. 1.背景 三年多前还在上研时,用C#+反射机制写过插件系统,后来又用MEF写过插件系统.插件系统本身具有易于扩展的优势,所以在实际项目中使用很频繁.即使在B/S项目中,插件的思想也是大行其道,比如前端单页面+AMD编程便可以理解为一种插件机制,以及后台扩展项目统一打包为一个jar放入主系统jar文件中一起发布,也可以理解为插件思想的运用. 这里我们回到C/S插件系统编

NET插件系统之一,开头:MEF的一些疑问和相关思考

      实现可扩展的软件系统是我一直的目标和想法.可扩展性显然属于动态编程的范畴.因此,几个月来我在业余时间会抽空学习插件系统.   我参考了博客园的几篇插件式系统的文章.知道了实现插件系统有以下的核心流程:       1. 定义插件接口,并在各个功能组件中实现这些接口 2. 在主程序中,通过遍历所需目录下的dll文件,查询实现该接口的type,从而通过createInstance方法实现其动态创建,并加入到主程序插件列表.下面的代码展示了该功能. public void GetAllPl