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

简介: 文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.背景 一般的WinForm中通过C#自带的Event机制便能很好的实现事件的注册和分发,但是,在插件系统中却不能这么简单的直接用已有的类来完成。

文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处: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/

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

                                

目录
相关文章
|
3天前
|
网络协议 C++
C++ Qt开发:QTcpSocket网络通信组件
`QTcpSocket`和`QTcpServer`是Qt中用于实现基于TCP(Transmission Control Protocol)通信的两个关键类。TCP是一种面向连接的协议,它提供可靠的、双向的、面向字节流的通信。这两个类允许Qt应用程序在网络上建立客户端和服务器之间的连接。Qt 是一个跨平台C++图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍如何运用`QTcpSocket`组件实现基于TCP的网络通信功能。
49 8
C++ Qt开发:QTcpSocket网络通信组件
|
3天前
|
存储 网络安全 C++
C++ Qt开发:QUdpSocket网络通信组件
Qt 是一个跨平台C++图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍如何运用`QUdpSocket`组件实现基于UDP的网络通信功能。与`QTcpSocket`组件功能类似,`QUdpSocket`组件是 Qt 中用于实现用户数据报协议(UDP,User Datagram Protocol)通信的类。UDP 是一种无连接的、不可靠的数据传输协议,它不保证数据包的顺序和可靠性,但具有低延迟和简单的特点。
22 0
C++ Qt开发:QUdpSocket网络通信组件
|
3天前
|
设计模式
二十三种设计模式全面解析-桥接模式的高级应用:构建灵活的跨平台UI框架
二十三种设计模式全面解析-桥接模式的高级应用:构建灵活的跨平台UI框架
|
前端开发 JavaScript 开发者
封装库/工具库中重要概念之UI框架
UI(User Interface)框架是前端开发中十分重要的一部分,它提供了各种组件和样式,用于构建页面和用户界面。在前端开发中,封装库/工具库可以帮助我们更加高效地使用 UI 框架。
151 0
|
存储 架构师 算法
架构设计的本质:系统与子系统、模块与组件、框架与架构
在软件研发这个领域,程序员的终极目标都是想成为一名合格的架构师。然而梦想很美好,但现实却很曲折。
架构设计的本质:系统与子系统、模块与组件、框架与架构
|
消息中间件 微服务
MassTransit 实现应用程序间交互
MassTransit 介绍  先看下masstransit 官网介绍:MassTransit 是一个自由、开源、轻量级的消息总线, 用于使用. NET 框架创建分布式应用程序。MassTransit 在现有消息传输上提供了一组广泛的功能, 从而使开发人员能够友好地使用基于消息的会话模式异步连接服务。
1866 0
|
Android开发
Android组件化开发实践(四):组件间通信问题
记得第一次实施项目组件化时,遇到的最大困扰就是,组件之间的通信问题。例如: 怎么从这个组件跳转到另一个组件的页面; 组件之间怎么传递数据; 怎么获取其他组件的数据或服务; 组件怎么通知其他组件响应某个事件; 1. 页面跳转统一采用路由 在Android中,页面跳转都是通过startActivity来实现的。
2032 0