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

研一时,听当时的师兄推荐,买了蒋波涛的一本关于GIS插件框架的书。当时一边看书一边将其中的例子完整的实现了一遍,收益匪浅。后来由于项目需要,也做过一个插件的C/S系统,用的是微软提供的MEF框架。在这个系统中,把蒋波涛在他的书中没有涉及到的插件和插件的通信完成了。不过,蒋波涛的那本书,涉及到了插件系统的很多底层内容,其中关于插件引擎的设计尤其值得学习。近来,我将自己当年实现的那个例子进行了一个总结,和大家一起分享。

1.插件式框架的组成

(1).框架分为宿主程序和插件对象两部分

(2).两部分交互基于一种公共的通信契约

(3).宿主程序可以独立存在

2.使用插件的原因

(1).可以在无需对程序进行重新编译和发布的条件下扩展程序的功能

(2).可以在不需要程序源代码的环境下为程序增加新的功能

(3).在一个程序的业务逻辑不断发生改变、新的规则频频加入时能够灵活适应

3.插件的一般实现技术

(1).基于动态链接库DLL的插件

(2).基于COM的插件

(3).基于反射技术的插件

4.细谈本框架的实现

4.1.设计全部并实现部分接口

接口分为:

宿主接口:IApplicaiton

插件接口:IPlugin(ICommand,Itool, IMenuDef,IToolBarDef,IDockableWindowDef)和不是继承于Ipluging的IItemDef

本章中,对继承于IApplication的Application和继承于ItemDef的ItemDef类进行了实现。类图如下:

4.2制作插件容器

在实例化的插件还没有被添加到宿主中时,需要一个寄存这些实例化的插件的宿主。

于是,我们在设计完插件接口后,还得做一个设计插件容器的工作。此容器只能存放继承于Iplugin的类。

4.2.1设计PluginCollection

首先:

继承CollectionBase抽象类。

因为CollectionBase已经实现了Ilist,Icolloction和Ienumerable等三个接口,为我们解决了大部分问题。

(其中主要重点是要覆盖一个新的GetEnumerator()方法,且此方法返回的是一个实现了IEnumerator接口的类.如果在重写这个方法时已经利用yield实现了迭代功能,则第二步可以跳过)。

然后:

写那个继承并实现了IEnumerator接口的类。(主要是重写Current,MoveNext,,Reset三个函数)

4.3设计PluginEngine中的反射机制

以上我们设计了通讯接口和接口容器,为什么说插件只有实现了这些接口中的一个才能被识别呢?

因为我们的接口引擎(PluginEngine)只能对这些接口进行识别。

那么何为接口引擎呢?

简单点说,在本系统中,就是利用反射后得到的每个TYPE的InterFace必须是我们以上规定的几个接口才能被识别和做出反应。

4.3.1细解动态加载和对象生成

反射机制是我们这个插件系统的核心技术。

它使得这些类都可以被动态加载和调用。

(1).本系统首先利用Directory.GetFiles()函数得到目标文件夹里的所有DLL文件。

(2).利用反射函数Assemly.LoadFrom加载文件(得到若干程序集)。再利用程序集的GetTypes()得到Type[]数组。

(3).最后利用Type类的GetInterfaces()得到每一个类所继承的接口。利用switch检查这个类是否继承过自定义的那些接口。若实现过,则利用Activator.CreateInstance(Type _type)这个方法来实例化这个类。最后将其加入到插件容器PluginCollection中。

4.4插件的分类

设置五个接口字典容器,分别是装ICommand,ITool,IToolBarDef,IMenuDef,IDockableWindowDef的五个容器和一个命令类型容器(其中将存放实现了ICommand和或者ITool的不重复的Category)。

注:这些容器中的Key值都是在实现这些接口的插件的名字。

4.5建立宿主框架

利用第三方控件Janus WinForms Controls V3.5来设计界面。

此三方控件中有两个控件,一个是UICommandManager,一个是UIPanelManager,这两个控件对插件的插入显示有很大的帮助

此宿主实例化时,首先实例化一个Apllication类,然后再给此实例中的MapControl,PageControl,MainPlantform的重要属性赋值。

所以通过这个被复制了的实例,宿主和插件的交互就不难实现了。

4.6插件获取

这是一个比较大的方面,也是核心之一了。也便是,怎么样能让宿主得到还保留在插件容器中的插件,并能显示在宿主中?

1.因为Command和Tool在UI上是同一类型,所以合在一起获取。

获取中,有两个地方要注意:一个是要使实例Create(hook ),即把宿主的相关信息类Application传递过去。第二个是,注册系统定义事件。例如UICommand+=new CommandEventHandler(UICommand_Click);

2.同理分别对继承了IMenuDef,IToolBarDef以及IDockableWindowDef的对象进行获取。

注:浮动窗体是由UIPanelManager进行托管的。也就是将悬浮框中的ChildHWND(Control类)加入到新panel中的panelContainer.Controls中。

4.7插件对象的事件处理

上一个步骤中,我们把一个未定义的事件处理方法通过自带委托注册到了Click事件中了。

那么这一节我们将具体来写这个事件处理方法。Command是交互的,Tool是不交互的。所以编写起来有很大差别。

这两个处理函数中,有两个共同的关键点:一个是利用e(CommandEventArgs类)的e.Command.Key得到在相关插件字典容器中放置的对象。第二个是都要触发对象的Click函数。

4.8框架插件设计

这节是系统以后也可以继续扩充的地方。

此处重点抓住cAddData这个插件的实现。

此类首先继承Icommand这个接口。在宿主窗体加载获取各插件而触发的create(Iapplication hook)方法中,调用Engine自带的ControlsAddDataCommandClass()类,并将其hook到传递过来的宿主的MapControl上去即可。

4.9宿主程序的高级设计

可以对宿主程序本身进行一些高级设计。比如使得mapControl和PageControl联动显示。比如制定TocControl的浮动菜单或者开发要素数据的查询显示等。

注意:此些设计都是对宿主本身而设计的,跟插件没关系。是最大程度上的利用宿主窗体本身。

4.10框架辅助组件框架库设计

此节完全是为了更方便的开发框架或其插件本身而设计的。

在此部分,可以把很多以后可能会用到的方法进行编写以及封装,以后开发便可以直接调用。

可以称本部分为系统开发包(SDK),但是此部分并非系统必备。

4.11系统发布

系统发布时首先要确定一个空机器上需要运行此系统起码需要哪些基本的平台。

此系统运行时对方机器上起码该装有:.NET 3.0 Framework可再分发组件包,Janus System UI V3.5 和ArcGIS Engine10 Runtime

然后利用InstallShield Express X来打包。

5结果展示

6.本框架的优劣及展望

6.1优势

本框架为纯底层开发,移植性和通用性比较好。具有一般的插件所具有的其他特点,例如易扩展,有一定的解耦性。符合面向接口和依赖倒转的编程思想,在本框架中,还集成了命令模式、观察者模式、遍历模式以及外观模式,单例模式。

6.2劣势

本框架划分的粒度太细,这样容易使类爆炸式增长。

本框架只实现了插件与宿主之间的通信,而没有实现插件与插件之间的通信。

6.3展望

解决插件与插件之间的通信,可单独做一个复杂通信的插件,然后其他插件均引用此插件。利用观察者模式,在宿主中加载插件后,便能实现事件注册,进而实现插件之间的通信。

同时,很多框架都实现了插件的编程思想。比利用Spring的依赖注入和微软提供的MEF所有的依赖注入,均能实现插件系统。

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

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

                                    

(1)从底层设计,探讨插件式GIS框架的实现的更多相关文章

  1. 插件式Web框架

    转载构建高性能插件式Web框架 基于MVC插件模式构建支持数据库集群.数据实时同步.数据发布与订阅的Web框架系统.如下图: 1.基于插件式开发 采用插件模式开发的优点是使得系统框架和业务模式有效地进 ...

  2. Asp.net MVC 插件式应用框架

    Asp.net MVC 插件式应用框架 2013年05月13日 10:16供稿中心: 互联网运营部 摘要:这几年来做了很多个网站系统,一直坚持使用asp.net mvc建站,每次都从头开始做Layou ...

  3. 构建高性能插件式Web框架

    基于MVC插件模式构建支持数据库集群.数据实时同步.数据发布与订阅的Web框架系统.如下图: 1.基于插件式开发 采用插件模式开发的优点是使得系统框架和业务模式有效地进行分离,系统更新也比较简单,只需 ...

  4. [连载]《C#通讯(串口和网络)框架的设计与实现》-2.框架的总体设计

    目       录 C#通讯(串口和网络)框架的设计与实现... 1 (SuperIO)- 框架的总体设计... 1 第二章           框架总体的设计... 2 2.1           ...

  5. 基于Flask的Web应用程序插件式结构开发

    事实上,很多应用程序基于插件式结构开发,可以很方便了扩展软件的功能,并且这些功能完全可以依托于第三方开发者,只要提供好接口和完备文档,比如wordpress.谷歌火狐浏览器等. Python这样的动态 ...

  6. 使用 SailingEase WinForm 框架构建复合式应用程序(插件式应用程序)

    对于一些较小的项目,具备一定经验的开发人员应该能够设计和构建出便于进行维护和扩展的应用程序.但是,随着功能模块数量(以及开发维护这些部件的人员)的不断增加,对项目实施控制的难度开始呈指数级增长. Sa ...

  7. Android应用插件式开发解决方法

    转自:http://blog.csdn.net/arui319/article/details/8109650 一.现实需求描述 一般的,一个Android应用在开发到了一定阶段以后,功能模块将会越来 ...

  8. C#实现插件式架构的方法

    插件式架构,一种全新的.开放性的.高扩展性的架构体系.插件式架构设计近年来非常流行,基于插件的设计好处很多,把扩展功能从框架中剥离出来,降低了框架的复杂度,让框架更容易实现.扩展功能与框架以一种很松的 ...

  9. AvalonDock 2.0+Caliburn.Micro+MahApps.Metro实现Metro风格插件式系统(一)

    随着IOS7由之前UI的拟物化设计变为如今的扁平化设计,也许扁平化的时代要来了,当然我们是不是该吐槽一下,苹果什么时候也开始跟风了,自GOOGLE和微软界面扁平化过后,苹果也加入了这一队伍. Aval ...

随机推荐

  1. 2016/11/16 周三 <Web SQL Database基本使用方法(入门) >

    <!doctype html> <html> <head> <meta charset="UTF-8"> <title> ...

  2. iOS开发——post异步网络请求封装

    IOS中有许多网络请求的函数,同步的,异步的,通过delegate异步回调的. 在做一个项目的时候,上网看了很多别人的例子,发现都没有一个简单的,方便的异步请求的封装例子.我这里要给出的封装代码,是异 ...

  3. CSS 基础语法

    注:CSS对大小写不敏感,但是如果涉及到与HTML文档一起工作的时候,class和id名称对大小写是敏感的 一.color color:#ff0000; color:#f00; //缩写 color: ...

  4. The Myths about Transactions (ACID) and NoSQL

    There has been widespread characterization of one of the major distinctions between NoSQL and tradit ...

  5. 实践.Net Core在Linux环境下的第一个Hello World

    基础环境和相关软件准备 1.CentOS7.1 64位系统(或者其他CentOS版本的64位系统) 2.WinSCP软件(主要是方便管理和编辑Linux系统的文件) 3.XShell软件(Window ...

  6. 梦想还需有,因它必实现——发现最新版iOS漏洞,OverSky团队专访

    梦想还需有,因它必实现——发现最新版iOS漏洞,OverSky团队专访    “成功了!”,随着一句欢呼声在阿里巴巴西溪园区传出,Cydia的图标出现在一部iOS9.3.4的iPhone6上并成功运行 ...

  7. ENode框架Conference案例分析系列之 - 复杂情况的读库更新设计

    问题背景 Conference案例,是一个关于在线创建会议(类似QCon这种全球开发者大会).在线管理会议位置信息.在线预订某个会议的位置的,这样一个系统.具体可以看微软的这个项目的主页:http:/ ...

  8. 微软CMS项目 Orchard 所用到的开源项目

    研发了Orchard一年左右了,时常遇到瓶颈,总觉得力不从心,其实并不是基础不够,关键还是概念性的东西太多,一会儿这个概念名词,一会那个,关于Orchard的技术文档也的确很少,每次看起来总是焦头烂额 ...

  9. 备忘-Android ViewPager 与Gallery滑动冲突解决方法

    解决方法,重新定义gallery,禁止触发pager的触摸事件 1 public class UserGallery extends Gallery implements OnGestureListe ...

  10. C#设计模式之工厂

    IronMan之工厂 前言 实用为主,学一些用得到的技术更能在如今的社会里保命. 虽然在日常的工作中设计模式不是经常的用到,但是呢,学习它只有好处没有坏处. 设计模式像是一种“标签”,它是代码编写者思 ...