




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
VisualC#插件構(gòu)架實戰(zhàn)一、引言問題的引入假設(shè)你設(shè)計的程序已經(jīng)部署到用戶的計算機上,并且能夠正常運行了。但是有一天,用戶打來了電話——他們要求增加新的功能。確定了用戶的需求后,你竟然發(fā)現(xiàn)原有的軟件架構(gòu)已經(jīng)無法勝任新增任務(wù)的需求——你需要重新設(shè)計這個應(yīng)用了!但問題是,就算你又用了一個開發(fā)周期完成了用戶需要的應(yīng)用,卻不能保證用戶的需求不會再次變更。也就是說,需求蔓延的可能性依然存在。因此,這種情況下插件構(gòu)架更能顯示出它的優(yōu)越性。幾個解決方案的對比我總結(jié)了一下我所接觸到的插件構(gòu)架,大致上可分為以下幾類:i>腳本式使用某種語言把插件的程序邏輯寫成腳本代碼。而這種語言可以是Python,或是其他現(xiàn)存的已經(jīng)經(jīng)過用戶長時間考驗的腳本語言。甚至,你可以自行設(shè)計一種腳本語言來配合你程序的特殊需要。當(dāng)然,用當(dāng)今最流行的XML是再合適不過了。這種形式的特點在于,稍有點編程知識的用戶就可以自行修改你的腳本(a_a假如你不加密它的話)。我們無法論證這是好處還是壞處。因為,這種情況所造成的后果是不可預(yù)知的。ii>動態(tài)函數(shù)庫DLL插件功能以動態(tài)庫函數(shù)的形式存在。主程序通過某種渠道(插件編寫者或某些工具)獲得插件DLL中的函數(shù)簽名,然后在合適的地方調(diào)用它們。用過Matlab的讀者都知道,Matlab中的各項功能幾乎都是些動態(tài)鏈入的函數(shù)。iii>聚合式顧名思義,就是把插件功能直接寫成EXE。主程序除了完成自己的職責(zé)外,還負責(zé)調(diào)度這些“插件”。我不喜歡這種形式。這使插件與插件之間,主程序與插件之間(主要是這一點)的信息交流困難了許多。巴比倫塔的失?。?]從某種程度上講就是信息交流無法實現(xiàn)造成的。iv>COM組件COM[2]的產(chǎn)生給這個世界增添了幾分活力。只有接口!我們的插件需要做的只是實現(xiàn)程序定義的接口。主程序不需要知道插件怎樣實現(xiàn)預(yù)定的功能,它只需要通過接口訪問插件,并提供主程序相關(guān)對象的接口。這樣一來,主程序與各插件之間的信息交流就變得異常簡單。并且,插件對于主程序來說是完全透明的。3.決策C#是面向?qū)ο蟮某绦蛟O(shè)計語言。它提供了interface關(guān)鍵字來直接定義接口。同時,System.Reflection命名空間也提供了訪問外部程序集的一系列相關(guān)對象。這就為我們在C#中實現(xiàn)插件構(gòu)架打下了堅實的基礎(chǔ)。下面,我們將以一個具有插件構(gòu)架的程序編輯器為例,來闡述這種構(gòu)架在C#中的實現(xiàn)。二、設(shè)計過程好了,現(xiàn)在我們準(zhǔn)備把所有的核心代碼都放在CSPluginKernel命名空間中。用VSIDE建立一個C#類庫工程。在命名空間CSPluginKernel中開始我們的代碼。1.接口設(shè)計我們的程序編輯器會向插件開放正在編輯的文檔對象。程序啟動后,就枚舉每一個插件并把它連接到主程序,同時傳遞主程序?qū)ο蟮慕涌?。插件可以通過這個接口來請求主程序?qū)ο蠡蛟L問主程序功能。根據(jù)上面的需求,我們首先需要一個主程序接口:publicinterfaceIApplicationObject(voidAlert(stringmsg);//產(chǎn)生一條信息voidShowInStatusBar(stringmsg);//將指定的信息顯示在狀態(tài)欄IDocumentObjectQueryCurrentDocument();//獲取當(dāng)前使用的文檔對象IDocumentObject[]QueryDocuments();//獲取所有的文檔對象//設(shè)置事件處理器voidSetDelegate(DelegateswhichOne,EventHandlertarger);}//目前只需要這一個事件publicenumDelegates(Delegate_ActiveDocumentChanged,}然后是IDocumentObject接口。插件通過這個接口訪問編輯器對象。//////編輯器對象必須實現(xiàn)這個接口///publicinterfaceIDocumentObject(//這些屬性是RichTextBox控件的相應(yīng)的屬性映射stringSelectionText(get;set;}ColorSelectionColor(get;set;}FontSelectionFont(get;set;}intSelectionStart(get;set;}intSelectionLength(get;set;}stringSelectionRTF(get;set;}boolHasChanges(get;}voidSelect(intstart,intlength);voidAppendText(stringstr);voidSaveFile(stringfileName);voidSaveFile();voidOpenFile(stringfileName);voidCloseFile();_} 這個接口不需要過多解釋。這里我只實現(xiàn)了RichTextBox控件少數(shù)的幾個方法,其他可能用得到的,讀者自行添加即可。再然后,根據(jù)插件在其生命周期里的行為,設(shè)計插件的接口。//////本程序的插件必須實現(xiàn)這個接口///publicinterfaceIPlugin(ConnectionResultConnect(IApplicationObjectapp);voidOnDestory();voidOnLoad();voidRun();}//////表示插件與主程序連接的結(jié)果///publicenumConnectionResult(Connection_Success,Connection_Failed}主程序會首先調(diào)用Connect。方法,并傳遞IApplicationObject給插件。插件在這個過程中做一些初始化工作。然后,插件的OnLoad()方法被調(diào)用。在這之后,當(dāng)主程序接收到調(diào)用插件的信號時(鍵盤鼠標(biāo)響應(yīng))就會調(diào)用插件的Run()方法來啟動這個插件。程序結(jié)束時,調(diào)用其OnDestory()方法。這樣,插件的生命才宣告結(jié)束。2.插件信息的存儲與獲取一個插件需要有它的名稱、版本等信息。作為設(shè)計者的你,也一定要留下你的尊姓大名和個人網(wǎng)站等用來宣傳自己。C#的新特性一一屬性,就是一個很好的解決方案。因此我們定義一個從System.Attribute繼承來的類PluginInfoArrtibute://////用來指定一個插件的相關(guān)信息IIIpublicclassPluginInfoAttribute:System.Attribute(//////Deprecated.Donotuse.///publicPluginInfoAttribute。{}publicPluginInfoAttribute(stringname,stringversion,stringauthor,stringwebpage,boolloadWhenStart){//細節(jié)已略去}publicstringName{get{return_Name;}}publicstringVersion{get{return_Version;}}publicstringAuthor{get{return_Author;}}publicstringWebpage{get{return_Webpage;}}publicboolLoadWhenStart{get{return_LoadWhenStart;}}//////用來存儲一些有用的信息///publicobjectTag{get{return_Tag;}set{_Tag=value;}}//////用來存儲序號///publicintIndex{get{return_Index;}set{_Index=value;}}privatestring_Name="";privatestring_Version="";privatestring_Author="";privatestring_Webpage="";privateobject_Tag=null;privateint_Index=0;//暫時不會用privatebool_LoadWhenStart=true;}用這個類修飾你的插件,并讓他實現(xiàn)IPlugin接口://////MyPluging1(Justfortest)///[PluginInfo("MyPluging1(Justfortest)","1.0","JackHHansen","/matrix2003b",true)]publicclassMyPlugin1:IPlugin(publicMyPlugin1()(}#regionIPlugin成員//細節(jié)已略去#endregionprivateIApplicationObject_App;privateIDocumentObject_CurDoc;}加載插件現(xiàn)在就得用到System.Refelction命名空間了。程序在啟動時會搜索plugins目錄下的每一個文件。對于每一個文件,如果它是一個插件,就用Assembly對象加載它。然后枚舉程序集中的每一個對象。判斷一個程序集是否為我們的插件的方法是判斷它是否直接或間接實現(xiàn)自IPlugin。用下面的函數(shù),傳遞從程序集枚舉的對象的System.Type。privateboolIsValidPlugin(Typet)(boolret=false;Type[]interfaces=t.GetInterfaces();foreach(TypetheInterfaceininterfaces)(if(the
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 客戶經(jīng)理年終個人工作總結(jié)模版
- 社區(qū)護理資源配置優(yōu)化策略
- 快速充電技術(shù)的探索
- 風(fēng)險管理套期保值講解
- 火電廠生產(chǎn)工藝流程
- 養(yǎng)老護理標(biāo)準(zhǔn)化流程
- 余姚四中教師考試試題及答案
- 有關(guān)古代法律的考試題及答案
- 銀行行長面試題目及答案
- 老人晨起護理
- 2025北京各區(qū)高三一模數(shù)學(xué)分類匯編解析 答案
- 第18課《井岡翠竹》 課件
- (四調(diào))武漢市2025屆高中畢業(yè)生四月調(diào)研考試 英語試卷
- 廣西壯族自治區(qū)2025年4月高三畢業(yè)班診斷學(xué)考試英語試卷(廣西三模)
- 2025年山東省棗莊市滕州市中考歷史模擬試卷(一)
- 2025華陽新材料科技集團有限公司招聘(500人)筆試參考題庫附帶答案詳解
- 2024年美睫技術(shù)考核試題及答案
- 運維崗筆試題及答案
- 余杭塘路(俞家圩路-光明路)工程環(huán)評報告
- 中國化的馬克思主義(毛澤東思想)概論知到課后答案智慧樹章節(jié)測試答案2025年春上海思博職業(yè)技術(shù)學(xué)院
- 民航綜合測試題及答案
評論
0/150
提交評論