SharpDevelop 是一個(gè)用于制作C#或者VB.NET的項(xiàng)目而設(shè)計(jì)的一個(gè)編輯器,同時(shí),這個(gè)編輯器本身就是使用C#開發(fā)的,而且公開了全部源代碼,因此這個(gè)工具本身也是學(xué)習(xí)C#以及軟件開發(fā)規(guī)范的一個(gè)很好材料。
SharpDevelop 這個(gè)輕型的開發(fā)工具支持多種程序語言,包括C#、java以及VB.NET,同時(shí)還支持多種語言界面,除了基于XML的文檔提示工具,SharpDevelop 5還包含了諸如用光標(biāo)插入、上下文動(dòng)作、代碼審查、增強(qiáng)的滾動(dòng)條、后臺(tái)語法檢查、鏈接模式、抑制問題、自動(dòng)命名變量等新功能。此外,開發(fā)人員將能夠使用Ctrl+F7組合鍵監(jiān)視表達(dá)式以及從剪貼板環(huán)粘貼內(nèi)容。
這個(gè)編輯器的界面風(fēng)格類似于Office XP以及VS.NET,這個(gè)編輯器可以支持書寫C#, ASP.NET, ADO.NET, XML, HTML 等多種代碼, 支持基于項(xiàng)目或者是文件的開發(fā),可以對(duì)C#, HTML, ASP, ASP.NET, VBscript, VB.NET, XML 提供彩色語法顯示支持,同時(shí)還可以把彩色的代碼輸出為HTML格式文件。你可以在代碼中做標(biāo)記,支持豐富的代碼模版以及外接插件。
SharpDevelop插件:
SharpDevelop的插件系統(tǒng)更加強(qiáng)大,它的整個(gè)系統(tǒng)的基礎(chǔ)就僅僅是一個(gè)插件管理系統(tǒng),而你看到的所有的界面、功能統(tǒng)統(tǒng)都是以插件的形式掛入的。在這樣的一個(gè)插件系統(tǒng)下,我們可以不修改基本系統(tǒng),僅僅使用插件就構(gòu)造出各種各樣不同的系統(tǒng)。
現(xiàn)在讓我們來看看它的插件系統(tǒng)。進(jìn)入到SharpDevelop的安裝目錄中,在Bin目錄下的SharpDevelop.exe 和 SharpDevelop.Core.dll是這個(gè)系統(tǒng)的基本的插件系統(tǒng)。在Addins目錄下有兩個(gè)后綴是addin的文件,其中一個(gè) SharpDevelopCore.addin 就是它的核心插件的定義(配置)文件,里面定義的各個(gè)功能模塊存在于Bin/Sharpdevelop.Base.dll 文件中,另外還有很多其他的插件定義在Addins目錄下的addin文件中。
分析SharpDevelop的代碼,首先要弄清楚幾個(gè)基本的概念,這些概念和我以前的預(yù)想有一些區(qū)別,我深入了代碼之后才發(fā)現(xiàn)我的困惑所在。
1、AddInTree 插件樹
SharpDevelop 中的插件被組織成一棵插件樹結(jié)構(gòu),樹的結(jié)構(gòu)是通過 Extension(擴(kuò)展點(diǎn))中定義的Path(路徑)來定義的,類似一個(gè)文件系統(tǒng)的目錄結(jié)構(gòu)。系統(tǒng)中的每一個(gè)插件都在配置文件中指定了 Extension,通過Extension中指定的 Path 掛到這棵插件樹上。在系統(tǒng)中可以通過 AddTreeSingleton對(duì)象來訪問各個(gè)插件,以實(shí)現(xiàn)插件之間的互動(dòng)。
2、 AddIn 插件
在 SharpDevelop 的概念中,插件是包含多個(gè)功能模塊的集合(而不是我過去認(rèn)為的一個(gè)功能模塊)。在文件的表現(xiàn)形式上是一個(gè)addin配置文件,在系統(tǒng)中對(duì)應(yīng) AddIn 類。
3、Extension 擴(kuò)展點(diǎn)
SharpDevelop中的每一個(gè)插件都會(huì)被掛到 AddInTree(插件樹) 中,而具體掛接到這個(gè)插件樹的哪個(gè)位置,則是由插件的 Extension 對(duì)象中的 Path 指定的。在addin 配置文件中,對(duì)應(yīng)于 <Extension> 。例如下面這個(gè)功能模塊的配置
lt;Extension path = "/SharpDevelop/Workbench/Ambiences">
<Class id = ".NET" class = "ICSharpCode.SharpDevelop.Services.NetAmbience"/>
</Extension>
指定了擴(kuò)展點(diǎn)路徑為 /SharpDevelop/Workbench/Ambiences ,也就是在插件樹中的位置。
4、Codon
這個(gè)是一個(gè)比較不好理解的東西,在 SharpDevelop 的三個(gè)作者寫的書的中譯版中被翻譯為密碼子,真是個(gè)糟糕的翻譯,可以跟Handle(句柄)有一拼了。詞典中還有一個(gè)翻譯叫“基碼”,我覺得這個(gè)也不算好,不過還稍微有那么一點(diǎn)意思。(這里我原來誤寫為“代碼子”,在評(píng)論中有位仁兄說這個(gè)翻譯不錯(cuò),現(xiàn)在我覺得也好像確實(shí)不錯(cuò) ^o^)
根據(jù)我對(duì)代碼的理解,Codon 的功能是描述(包裝)一個(gè)功能模塊(一個(gè)功能模塊對(duì)應(yīng)一個(gè)實(shí)現(xiàn)了具體功能的 Command 類)。為了方便訪問各個(gè)插件中的功能模塊, Codon 給各種功能定義了基本的屬性,分別是 ID (功能模塊的標(biāo)識(shí)),Name (功能模塊的類型。別誤會(huì),這個(gè)Name 是addin文件定義中Codon的XML結(jié)點(diǎn)的名稱,ID才是真正的名稱),其中Name可能是Class(類)、MenuItem(菜單項(xiàng))、Pad(面板)等等。根據(jù)具體的功能模塊,可以繼承Codon定義其他的一些屬性,SharpDevelop中就定義了 ClassCodon、MenuItemCodon、PadCodon等等,你可以根據(jù)需要自己定義其他類型的Codon。在addin定義文件中,Codon對(duì)應(yīng)于 <Extension> 標(biāo)簽下的內(nèi)容。例如下面這個(gè)定義
lt;Extension path = "/SharpDevelop/Workbench/Ambiences">
<Class id = ".NET" class = "ICSharpCode.SharpDevelop.Services.NetAmbience"/>
</Extension>
<Extension ...> 內(nèi)部定義了一個(gè)Codon,<Class ...> 表示該Codon是一個(gè) Class(類),接著定義了該Codon的 ID和具體實(shí)現(xiàn)該Codon的類名ICSharpCode.SharpDevelop.Services.NetAmbience。運(yùn)行期間將通過反射來找到對(duì)應(yīng)的類并創(chuàng)建出來,這一點(diǎn)也是我們無法在以前的語言中實(shí)現(xiàn)的。
再例如這一個(gè)定義
<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>
這個(gè)擴(kuò)展點(diǎn)中定義了三個(gè)菜單項(xiàng),以及各個(gè)菜單項(xiàng)的名字、標(biāo)簽和實(shí)現(xiàn)的類名。這里的Codon就對(duì)應(yīng)于系統(tǒng)中的MenuCodon對(duì)象。
5、Command 命令
正如前文所述,Codon描述了一個(gè)功能模塊,而每個(gè)功能模塊都是一個(gè) ICommand 的實(shí)現(xiàn)。最基本的 Command 是 AbstractCommand,根據(jù)Codon的不同對(duì)應(yīng)了不同的 Command。例如 MenuItemCodon 對(duì)應(yīng) MenuItemCommand 等等。
6、Service 服務(wù)
插件系統(tǒng)中,有一些功能是整個(gè)系統(tǒng)都要使用的,例如文件訪問、資源、消息等等。這些功能都作為插件系統(tǒng)的一個(gè)基本功能為整個(gè)系統(tǒng)提供服務(wù),我們就叫“服務(wù)”好了。為了便于訪問,這些服務(wù)都統(tǒng)一通過 ServiceManager 來管理。其實(shí)服務(wù)也是一種類型的插件,它們的擴(kuò)展點(diǎn)路徑在目錄樹中的 /Workspace/Services 中。
理解了這幾個(gè)基本的概念之后,就可以看看 SharpDevelop 的代碼了。從 src/main/startup.cs 看起吧,之后是addin.cs、addinTree.cs 等等。‍