SharpDevelop代碼分析 (一、序+基本概念)

    最近開始學習.Net,遇到了一個比較不錯的開源的IDE SharpDevelop。這個開發工具是使用C#開發的,比較吸引我的一點就是它是採用了和Eclipse類似的插件技術來實現整個系統的。而這個插件系統是我最感興趣的地方,因此開始了一段代碼的研究。在本篇之後,我會陸續把我研究的心得寫下來。由於是在網吧上網,有諸多不便,因此可能會拖比較長的時間。 一、基本概念     首先,我們先來對 SharpDevelop 有一個比較感性的認識。你可以從這裏下載到它的可執行程序和代碼包    http://www.icsharpcode.com/  ,安裝的廢話就不說了,先運行一下看看。感覺跟VS很像吧?不過目前的版本是1.0.0.1550,還有很多地方需要完善。關於代碼和系統結構,SharpDevelop的三個作者寫了一本書,各位看官可以參考一下,不過我看過之後還是有很多地方不太理解。     然後,讓我來解釋一下什麼叫插件以及爲什麼要使用插件系統。我們以往的系統,開發人員編譯發佈之後,系統就不允許進行更改和擴充了,如果要進行某個功能的擴充,則必須要修改代碼重新編譯發佈。這就給我們帶來了比較大的不方便。解決的方法有很多,例如提供配置等等方法。在解決方案之中,插件是一個比較好的解決方法。大家一定知道PhotoShop、WinAmp吧,他們都有“插件”的概念,允許其他開發人員根據系統預定的接口編寫擴展功能(例如PhotoShop中各種各樣的濾鏡)。所謂的插件就是系統的擴展功能模塊,這個模塊是以一個獨立文件的形式出現的,與系統是相對獨立。在系統設計期間並不知道插件的具體功能,僅僅是在系統中爲插件留下預定的接口,系統啓動的時候根據插件的配置尋找插件,根據預定的接口把插件掛接到系統中。     這樣的方式帶來什麼樣的優點呢?首先是系統的擴展性大大的增強了,如果我們在系統發佈後需要對系統進行擴充,不必重新編譯,只需要修改插件就可以了。其次有利與團隊開發,各個功能模塊由於是以插件的形式表現在系統中,系統的每日構造就很簡單了,不會因爲某個模塊的錯誤而導致整個系統的BUILD失敗。失敗的僅僅是一個插件而已。     PhotoShop和Winamp的插件系統是比較簡單的,他們首先實現了一個基本的系統,然後在這個系統的基礎上掛接其他擴展的功能插件。而SharpDevelop的插件系統更加強大,它的整個系統的基礎就僅僅是一個插件管理系統,而你看到的所有的界面、功能統統都是以插件的形式掛入的。在這樣的一個插件系統下,我們可以不修改基本系統,僅僅使用插件就構造出各種各樣不同的系統。     現在讓我們來看看它的插件系統。進入到SharpDevelop的安裝目錄中,在Bin目錄下的SharpDevelop.exe 和 SharpDevelop.Core.dll是這個系統的基本的插件系統。在Addins目錄下有兩個後綴是addin的文件,其中一個 SharpDevelopCore.addin 就是它的核心插件的定義(配置)文件,裏面定義的各個功能模塊存在於Bin/Sharpdevelop.Base.dll 文件中,另外還有很多其他的插件定義在Addins目錄下的addin文件中。     分析SharpDevelop的代碼,首先要弄清楚幾個基本的概念,這些概念和我以前的預想有一些區別,我深入了代碼之後才發現我的困惑所在。 1、AddInTree  插件樹     SharpDevelop 中的插件被組織成一棵插件樹結構,樹的結構是通過 Extension(擴展點)中定義的Path(路徑)來定義的,類似一個文件系統的目錄結構。系統中的每一個插件都在配置文件中指定了 Extension,通過Extension中指定的 Path 掛到這棵插件樹上。在系統中可以通過 AddTreeSingleton對象來訪問各個插件,以實現插件之間的互動。 2、 AddIn 插件     在 SharpDevelop 的概念中,插件是包含多個功能模塊的集合(而不是我過去認爲的一個功能模塊)。在文件的表現形式上是一個addin配置文件,在系統中對應 AddIn 類。 3、Extension 擴展點     SharpDevelop中的每一個插件都會被掛到 AddInTree(插件樹) 中,而具體掛接到這個插件樹的哪個位置,則是由插件的 Extension 對象中的 Path 指定的。在addin 配置文件中,對應於 <Extension> 。例如下面這個功能模塊的配置 <Extension path = "/SharpDevelop/Workbench/Ambiences">          <Class id    = ".NET" class = "ICSharpCode.SharpDevelop.Services.NetAmbience"/>  </Extension> 指定了擴展點路徑爲 /SharpDevelop/Workbench/Ambiences ,也就是在插件樹中的位置。 4、Codon     這個是一個比較不好理解的東西,在 SharpDevelop 的三個作者寫的書的中譯版中被翻譯爲代碼子,真是個糟糕的翻譯,可以跟Handle(句柄)有一拼了。詞典中還有一個翻譯叫“基碼”,我覺得這個也不算好,不過還稍微有那麼一點意思。     根據我對代碼的理解,Codon 描述(包裝)一個功能模塊,一個功能模塊對應一個實現了具體功能的 Command 類。爲了方便訪問各個插件中的功能模塊, Codon 給各種功能定義了基本的屬性,分別是 ID (功能模塊的標識),Name (功能模塊的類型。別誤會,這個Name 是addin文件定義中Codon的XML結點的名稱,ID纔是真正的名稱),其中Name可能是Class(類)、MenuItem(菜單項)、Pad(面板)等等。根據具體的功能模塊,可以繼承Codon定義其他的一些屬性,SharpDevelop中就定義了 ClassCodon、MenuCodon、PadCodon等等。 在addin定義文件中,Codon對應於 <Extension> 標籤下的內容。    例如下面這個定義 <Extension path = "/SharpDevelop/Workbench/Ambiences">          <Class id    = ".NET" class = "ICSharpCode.SharpDevelop.Services.NetAmbience"/>  </Extension> <Extension ...> 內部定義了一個Codon,<Class ...>  表示該Codon是一個 Class(類),接着定義了該Codon的 ID和具體實現該Codon的類名ICSharpCode.SharpDevelop.Services.NetAmbience。運行期間將通過反射來找到對應的類並創建出來,這一點也是我們無法在以前的語言中實現的。 再例如這一個定義  <Extension path = "/SharpDevelop/Views/ProjectBrowser/ContextMenu/CombineBrowserNode">                 <MenuItem id = "Compile"                           label = "${res:XML.MainMenu.RunMenu.Compile}"                           class = "ICSharpCode.SharpDevelop.Commands.Compile"/>                 <MenuItem id = "CompileAll"                           label = "${res:XML.MainMenu.RunMenu.CompileAll}"                           class = "ICSharpCode.SharpDevelop.Commands.CompileAll"/>                 <MenuItem id = "CombineBuildGroupSeparator" label = "-" />  .... </Extension> 這個擴展點中定義了三個菜單項,以及各個菜單項的名字、標籤和實現的類名。這裏的Codon就對應於系統中的MenuCodon對象。 5、Command 命令     正如前文所述,Codon描述了一個功能模塊,而每個功能模塊都是一個 ICommand 的實現。最基本的 Command 是  AbstractCommand,根據Codon的不同對應了不同的 Command。例如 MenuCodon 對應 MenuCommand 等等。 6、Service 服務     插件系統中,有一些功能是整個系統都要使用的,例如文件訪問、資源、消息等等。這些功能都作爲插件系統的一個基本功能爲整個系統提供服務,我們就叫“服務”好了。爲了便於訪問,這些服務都統一通過 ServiceManager 來管理。其實服務也是一種類型的插件,它們的擴展點路徑在目錄樹中的 /Services 中。     理解了這幾個基本的概念之後,就可以看看 SharpDevelop 的代碼了。從 src/main/startup.cs 看起吧,之後是addin.cs、addinTree.cs 等等。    寫了兩個小時了,休息一下。且聽下回分解吧。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章