国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

(1)從底層設(shè)計(jì),探討插件式GIS框架的實(shí)現(xiàn)

2019-11-17 02:59:42
字體:
供稿:網(wǎng)友

(1)從底層設(shè)計(jì),探討插件式GIS框架的實(shí)現(xiàn)

三年前,聽當(dāng)時(shí)的師兄推薦,買了蔣波濤的一本關(guān)于GIS插件框架的書。當(dāng)時(shí)一邊看書一邊將其中的例子完整的實(shí)現(xiàn)了一遍,收益匪淺。后來由于項(xiàng)目需要,也做過一個(gè)插件的C/S系統(tǒng),用的是微軟提供的MEF框架。在這個(gè)系統(tǒng)中,把蔣波濤在他的書中沒有涉及到的插件和插件的通信完成了。不過,蔣波濤的那本書,涉及到了插件系統(tǒng)的很多底層內(nèi)容,其中關(guān)于插件引擎的設(shè)計(jì)尤其值得學(xué)習(xí)。近來,我將自己當(dāng)年實(shí)現(xiàn)的那個(gè)例子進(jìn)行了一個(gè)總結(jié),和大家一起分享。

1.插件式框架的組成

(1).框架分為宿主程序和插件對(duì)象兩部分

(2).兩部分交互基于一種公共的通信契約

(3).宿主程序可以獨(dú)立存在

2.使用插件的原因

(1).可以在無需對(duì)程序進(jìn)行重新編譯和發(fā)布的條件下擴(kuò)展程序的功能

(2).可以在不需要程序源代碼的環(huán)境下為程序增加新的功能

(3).在一個(gè)程序的業(yè)務(wù)邏輯不斷發(fā)生改變、新的規(guī)則頻頻加入時(shí)能夠靈活適應(yīng)

3.插件的一般實(shí)現(xiàn)技術(shù)

(1).基于動(dòng)態(tài)鏈接庫DLL的插件

(2).基于COM的插件

(3).基于反射技術(shù)的插件

4.細(xì)談本框架的實(shí)現(xiàn)

4.1.設(shè)計(jì)全部并實(shí)現(xiàn)部分接口

接口分為:

宿主接口:IApplicaiton

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

本章中,對(duì)繼承于Iapplication的Application和繼承于ItemDef的ItemDef類進(jìn)行了實(shí)現(xiàn)。類圖如下:

4.2制作插件容器

在實(shí)例化的插件還沒有被添加到宿主中時(shí),需要一個(gè)寄存這些實(shí)例化的插件的宿主。

于是,我們?cè)谠O(shè)計(jì)完插件接口后,還得做一個(gè)設(shè)計(jì)插件容器的工作。此容器只能存放繼承于Iplugin的類。

4.2.1設(shè)計(jì)PluginCollection

首先:

繼承CollectionBase抽象類。

因?yàn)镃ollectionBase已經(jīng)實(shí)現(xiàn)了Ilist,Icolloction和Ienumerable等三個(gè)接口,為我們解決了大部分問題。

(其中主要重點(diǎn)是要覆蓋一個(gè)新的GetEnumerator()方法,且此方法返回的是一個(gè)實(shí)現(xiàn)了IEnumerator接口的類.如果在重寫這個(gè)方法時(shí)已經(jīng)利用yield實(shí)現(xiàn)了迭代功能,則第二步可以跳過)。

然后:

寫那個(gè)繼承并實(shí)現(xiàn)了IEnumerator接口的類。(主要是重寫Current,MoveNext,,Reset三個(gè)函數(shù))

4.3設(shè)計(jì)PluginEngine中的反射機(jī)制

以上我們?cè)O(shè)計(jì)了通訊接口和接口容器,為什么說插件只有實(shí)現(xiàn)了這些接口中的一個(gè)才能被識(shí)別呢?

因?yàn)槲覀兊慕涌谝妫≒luginEngine)只能對(duì)這些接口進(jìn)行識(shí)別。

那么何為接口引擎呢?

簡(jiǎn)單點(diǎn)說,在本系統(tǒng)中,就是利用反射后得到的每個(gè)TYPE的InterFace必須是我們以上規(guī)定的幾個(gè)接口才能被識(shí)別和做出反應(yīng)。

4.3.1細(xì)解動(dòng)態(tài)加載和對(duì)象生成

反射機(jī)制是我們這個(gè)插件系統(tǒng)的核心技術(shù)。

它使得這些類都可以被動(dòng)態(tài)加載和調(diào)用。

(1).本系統(tǒng)首先利用Directory.GetFiles()函數(shù)得到目標(biāo)文件夾里的所有DLL文件。

(2).利用反射函數(shù)Assemly.LoadFrom加載文件(得到若干程序集)。再利用程序集的GetTypes()得到Type[]數(shù)組。

(3).最后利用Type類的GetInterfaces()得到每一個(gè)類所繼承的接口。利用switch檢查這個(gè)類是否繼承過自定義的那些接口。若實(shí)現(xiàn)過,則利用Activator.CreateInstance(Type _type)這個(gè)方法來實(shí)例化這個(gè)類。最后將其加入到插件容器PluginCollection中。

4.4插件的分類

設(shè)置五個(gè)接口字典容器,分別是裝ICommand,ITool,IToolBarDef,IMenuDef,IDockableWindowDef的五個(gè)容器和一個(gè)命令類型容器(其中將存放實(shí)現(xiàn)了ICommand和或者ITool的不重復(fù)的Category)。

注:這些容器中的Key值都是在實(shí)現(xiàn)這些接口的插件的名字。

4.5建立宿主框架

利用第三方控件Janus WinForms Controls V3.5來設(shè)計(jì)界面。

此三方控件中有兩個(gè)控件,一個(gè)是UICommandManager,一個(gè)是UIPanelManager,這兩個(gè)控件對(duì)插件的插入顯示有很大的幫助

此宿主實(shí)例化時(shí),首先實(shí)例化一個(gè)Apllication類,然后再給此實(shí)例中的MapControl,PageControl,MainPlantform的重要屬性賦值。

所以通過這個(gè)被復(fù)制了的實(shí)例,宿主和插件的交互就不難實(shí)現(xiàn)了。

4.6插件獲取

這是一個(gè)比較大的方面,也是核心之一了。也便是,怎么樣能讓宿主得到還保留在插件容器中的插件,并能顯示在宿主中?

1.因?yàn)镃ommand和Tool在UI上是同一類型,所以合在一起獲取。

獲取中,有兩個(gè)地方要注意:一個(gè)是要使實(shí)例Create(hook ),即把宿主的相關(guān)信息類Application傳遞過去。第二個(gè)是,注冊(cè)系統(tǒng)定義事件。例如UICommand+=new CommandEventHandler(UICommand_Click);

2.同理分別對(duì)繼承了IMenuDef,IToolBarDef以及IDockableWindowDef的對(duì)象進(jìn)行獲取。

注:浮動(dòng)窗體是由UIPanelManager進(jìn)行托管的。也就是將懸浮框中的ChildHWND(Control類)加入到新panel中的panelContainer.Controls中。

4.7插件對(duì)象的事件處理

上一個(gè)步驟中,我們把一個(gè)未定義的事件處理方法通過自帶委托注冊(cè)到了Click事件中了。

那么這一節(jié)我們將具體來寫這個(gè)事件處理方法。Command是交互的,Tool是不交互的。所以編寫起來有很大差別。

這兩個(gè)處理函數(shù)中,有兩個(gè)共同的關(guān)鍵點(diǎn):一個(gè)是利用e(CommandEventArgs類)的e.Command.Key得到在相關(guān)插件字典容器中放置的對(duì)象。第二個(gè)是都要觸發(fā)對(duì)象的Click函數(shù)。

4.8框架插件設(shè)計(jì)

這節(jié)是系統(tǒng)以后也可以繼續(xù)擴(kuò)充的地方。

此處重點(diǎn)抓住cAddData這個(gè)插件的實(shí)現(xiàn)。

此類首先繼承Icommand這個(gè)接口。在宿主窗體加載獲取各插件而觸發(fā)的create(Iapplication hook)方法中,調(diào)用Engine自帶的ControlsAddDataCommandClass()類,并將其hook到傳遞過來的宿主的MapControl上去即可。

4.9宿主程序的高級(jí)設(shè)計(jì)

可以對(duì)宿主程序本身進(jìn)行一些高級(jí)設(shè)計(jì)。比如使得mapControl和PageControl聯(lián)動(dòng)顯示。比如制定TocControl的浮動(dòng)菜單或者開發(fā)要素?cái)?shù)據(jù)的查詢顯示等。

注意:此些設(shè)計(jì)都是對(duì)宿主本身而設(shè)計(jì)的,跟插件沒關(guān)系。是最大程度上的利用宿主窗體本身。

4.10框架輔助組件框架庫設(shè)計(jì)

此節(jié)完全是為了更方便的開發(fā)框架或其插件本身而設(shè)計(jì)的。

在此部分,可以把很多以后可能會(huì)用到的方法進(jìn)行編寫以及封裝,以后開發(fā)便可以直接調(diào)用。

可以稱本部分為系統(tǒng)開發(fā)包(SDK),但是此部分并非系統(tǒng)必備。

4.11系統(tǒng)發(fā)布

系統(tǒng)發(fā)布時(shí)首先要確定一個(gè)空機(jī)器上需要運(yùn)行此系統(tǒng)起碼需要哪些基本的平臺(tái)。

此系統(tǒng)運(yùn)行時(shí)對(duì)方機(jī)器上起碼該裝有:.NET 3.0 Framework可再分發(fā)組件包,Janus System UI V3.5 和ArcGIS Engine10 Runtime

然后利用InstallShield ExPRess X來打包。

5結(jié)果展示

6.本框架的優(yōu)劣及展望

6.1優(yōu)勢(shì)

本框架為純底層開發(fā),移植性和通用性比較好。具有一般的插件所具有的其他特點(diǎn),例如易擴(kuò)展,有一定的解耦性。符合面向接口和依賴倒轉(zhuǎn)的編程思想,在本框架中,還集成了命令模式、觀察者模式、遍歷模式以及外觀模式,單例模式。

6.2劣勢(shì)

本框架劃分的粒度太細(xì),這樣容易使類爆炸式增長(zhǎng)。

本框架只實(shí)現(xiàn)了插件與宿主之間的通信,而沒有實(shí)現(xiàn)插件與插件之間的通信。

6.3展望

解決插件與插件之間的通信,可單獨(dú)做一個(gè)復(fù)雜通信的插件,然后其他插件均引用此插件。利用觀察者模式,在宿主中加載插件后,便能實(shí)現(xiàn)事件注冊(cè),進(jìn)而實(shí)現(xiàn)插件之間的通信。

同時(shí),很多框架都實(shí)現(xiàn)了插件的編程思想。比利用Spring的依賴注入和微軟提供的MEF所有的依賴注入,均能實(shí)現(xiàn)插件系統(tǒng)。


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 循化| 甘德县| 义马市| 卢龙县| 微博| 黔江区| 元氏县| 东乡县| 谢通门县| 樟树市| 庆元县| 商水县| 社旗县| 丹东市| 宜宾县| 合肥市| 咸丰县| 富锦市| 涡阳县| 行唐县| 张家口市| 甘孜县| 依安县| 商南县| 当雄县| 锦州市| 通州区| 晋州市| 黄骅市| 鲜城| 广平县| 两当县| 达州市| 伊宁市| 和龙市| 达孜县| 连云港市| 古田县| 杭锦旗| 承德县| 合江县|