SharpDevelop源碼分析 (二、主程式+隱藏的初始化)

來源:互聯網
上載者:User

    在大學課程裡面,我對於類比電路總是搞不清楚,直到現在也是這樣。我總覺得電路圖很奇怪,總會問“這部分電路是做什麼用的”、“為什麼會有這樣的效果”。在我的腦海裡面,每部分的電路都應該有一定的用處,可是我總是看不明白。我媽媽說,我的思路被軟體所固化的太久了,看電路圖不應該總是一個個模組的看,正確的方法應該是從電源的一極順著電路看,一直看到電源的另一極。我現在仍然不懂看電路圖,可是以我看代碼的經驗來說,我覺得分析原始碼按照這樣的思路來看會比較容易把脈絡理清楚。
     在SharpDevelop的代碼中,由於很多的介面和外掛程式的原因,很多代碼在看到某個地方會突然失去函數/方法調用的線索。例如看某個函數的實現的時候會跳到一個介面裡面去,那是因為這部分功能在運行期才會給一個實現了這個介面的對象來進行具體的執行。從這個角度來說,設計模式也給我們研究代碼稍微帶來了一點小小的難度。在看Linux下原始碼的時候也經常遇到這種問題,在這個時候尋找代碼線索比較好的方法是用一個文本搜尋工具來搜尋相關的關鍵字。在Linux下我經常會用grep,Windows下面類似UltraEdit的“批量檔案尋找”功能會很好用(或者“Search And Replace”之類的工具)。這個是我讀代碼的一點小小的經驗,如果你知道有更好的方法,請告訴我讓我也學習一下 ? 。
     我不想大段大段的貼代碼出來佔地方(空間、頻寬,還有各位看官的注意力),在需要的地方我會貼上主要的代碼,因此最好能夠找代碼來對應著看。把程式碼封裝解壓縮,我把它解到了“F:\SharpDevelop”(如果沒有說明,下文都是以此為代碼的根目錄了)。由於SharpDevelop本身對於察看代碼不是很方便,沒有“轉到定義”之類的功能,因此我建議你把它的代碼轉成VS的工程來看。不過很可惜,SharpDevelop的工程匯出功能現在有問題,如果匯出\src\SharpDevelop.cmbx 這個總的複合工程的話會失敗(我記得RC1版本是可以成功的,不知道為什麼後來的版本反而會出問題),所以只能一個一個工程的匯出。
     好了,讓我們來看SharpDevelop的代碼吧。
1、起點
    在主程式的起點在\src\Main\StartUp\SharpDevelopMain.cs,找到Main函數這就是整個程式的起點了。開始的部分是顯示封面表單並加上命令列控制,其中SplashScreenForm 定義在\src\Main\Base\Gui\Dialogs\SplashScreen.cs檔案中,這部分我就不多說了。之後是

Application.ThreadException += new ThreadExceptionEventHandler(ShowErrorBox);

    SharpDevelop為了有效進行錯誤報表,因此自己進行了異常的控制。系統出現異常的時候,SharpDevelop會攔截下來彈出它自己的異常提示報告對話方塊。這個代碼就是在這一行實現的。其中 ShowErrorBox 這個方法就在類SharpDevelopMain中,ExceptionBox 定義在\src\Main\StartUp\Dialogs\ExceptionBox.cs中。如果需要進行自己的異常控制,可以學習一下這裡的技巧。

2、充滿玄機的初始化

string [] addInDirs = ICSharpCode.SharpDevelop.AddInSettingsHandler.GetAddInDirectories( out ignoreDefaultPath );
AddInTreeSingleton.SetAddInDirectories(addInDirs, ignoreDefaultPath);

    通過AddInSettingsHandler取得外掛程式的目錄,並告知AddInTreeSingleton。AddInSettingsHandler定義在\src\Main\StartUp\Dialogs\AddInTreeSettingsHandler.cs中,它通過讀取系統配置(App.config)檔案中的AddInDirectory節點的Path屬性來確定外掛程式的目錄位置,或者你也可以通過自己定義的AddInDirectories節來指定外掛程式目錄。如果你沒有做這些配置,預設的目錄在SharpDevelop運行目錄的..\Addins目錄下。

ServiceManager.Services.AddService(new MessageService());
ServiceManager.Services.AddService(new ResourceService());
ServiceManager.Services.AddService(new IconService());

    通過ServiceManager(服務管理員)加入三個系統預設的服務,Message Service、資源服務、表徵圖服務。這三個服務中,Message Service是顯示各種資訊提示,另外兩個是屬於系統的資源,SharpDevelop通過服務來進行統一調用和管理。
ServiceManager.Services.InitializeServicesSubsystem("/Workspace/Services");

    初始化其他的服務。SharpDevelop把服務定義在外掛程式樹的/Workspace/Services這個路徑中,凡是在這個路徑下的外掛程式都被認為是服務,因此如果你自己定義了一個服務的話,也需要掛到這個路徑下(這裡就是系統服務的擴充點了)。

    注意!這一步中,在我們的眼皮子底下悄悄的進行了一個重要的初始化工作。各位看官請看,ServiceManager 定義在\src\Main\Core\Services\ ServiceManager.cs檔案中,察看它的InitializeServicesSubsystem方法,我們發現這樣一行

AddServices((IService[]) AddInTreeSingleton.AddInTree.GetTreeNode(servicesPath).BuildChildItems(this).ToArray(typeof(IService)));

    在這裡,AddInTreeSingleton首次調用了AddInTree(外掛程式樹)的執行個體。按照Singleton模式,只有在首次調用的時候才會初始化執行個體,這裡也是同樣如此。整個系統的AddInTree是在這一步中進行了初始化工作,稍候我們將詳細介紹AddInTree如何進行初始化工作,先順便看看服務的初始化。在ServiceManager的InitializeServicesSubsystem方法中,通過AddInTree檢索服務外掛程式路徑下的所有配置,並通過它來讀取、建立具體的對象,然後加入到服務列表中。之後通過一個迴圈,逐個的調用各個服務的InitializeService方法初始化服務。

    AddInTree的初始化工作容我們稍候再看,先把主體的代碼看完。

commands = AddInTreeSingleton.AddInTree.GetTreeNode("/Workspace/Autostart").BuildChildItems(null);
for (int i = 0; i < commands.Count - 1; ++i)
{
 ((ICommand)commands[i]).Run();
}

    /Workspace/Autostart是系統自動運行命令的擴充點路徑,定義在這個路徑下的外掛程式會在系統啟動的時候自動運行。在這裡,通過外掛程式樹初始化建立處於這個路徑下的Command(命令),並逐一執行。BuildChildItems方法的功能是建立這個擴充點下的Command列表,我會在介紹AddTree的時候具體說明它的實現。

     主程式碼的最後,初始化完畢、關閉封面表單,然後執行命令列表中最後一個命令(也就是系統的主介面)。在主介面退出的時候,系統卸載所有的服務。

    在這部分代碼中,我們知道了兩個系統指定的擴充點路徑 /Workspace/Services 和 /Workspace/Autostart ,我們實現服務和指定系統自動運行命令的時候就可以掛到這兩個擴充點路徑下了。
     托反射的福,ServiceManager.Services可以通過類型(介面)來尋找具體的執行個體,也就是GetServices方法。但是ServiceManager的具體實現我們可以容後再看,這裡已經不是最緊要的部分了。
     接下來,我們來看看整個外掛程式系統的核心-AddinTree的代碼,看看它是如何通過外掛程式配置進行初始化並建立起整個系統的外掛程式樹骨幹。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.