程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#基礎知識 >> Visual C# 插件構架實戰

Visual C# 插件構架實戰

編輯:C#基礎知識

  一、引言

  1. 問題的引入

  假設你設計的程序已經部署到用戶的計算機上,並且能夠正常運行了。但是有一天,用戶打來了電話——他們要求增加新的功能。確定了用戶的需求後,你竟然發現原有的軟件架構已經無法勝任新增任務的需求——你需要重新設計這個應用了!但問題是,就算你又用了一個開發周期完成了用戶需要的應用,卻不能保證用戶的需求不會再次變更。也就是說,需求蔓延的可能性依然存在。因此,這種情況下插件構架更能顯示出它的優越性。

  2. 幾個解決方案的對比

  我總結了一下我所接觸到的插件構架,大致上可分為以下幾類:

  i> 腳本式

  使用某種語言把插件的程序邏輯寫成腳本代碼。而這種語言可以是 Python ,或是其他現存的已經經過用戶長時間考驗的腳本語言。甚至,你可以自行設計一種腳本語言來配合你程序的特殊需要。當然,用當今最流行的 XML 是再合適不過了。

  這種形式的特點在於,稍有點編程知識的用戶就可以自行修改你的腳本( ^_^ 假如你不加密它的話)。我們無法論證這是好處還是壞處。因為,這種情況所造成的後果是不可預知的。

  ii> 動態函數庫 DLL

  插件功能以動態庫函數的形式存在。主程序通過某種渠道(插件編寫者或某些工具)獲得插件 DLL 中的函數簽名,然後在合適的地方調用它們。用過 Matlab 的讀者都知道, Matlab 中的各項功能幾乎都是些動態鏈入的函數。

  iii> 聚合式

  顧名思義,就是把插件功能直接寫成 EXE 。主程序除了完成自己的職責外,還負責調度這些“插件”。我不喜歡這種形式。這使插件與插件之間,主程序與插件之間(主要是這一點)的信息交流困難了許多。巴比倫塔的失敗 [1] 從某種程度上講就是信息交流無法實現造成的。

  iv> COM 組件

  COM [2] 的產生給這個世界增添了幾分活力。只有接口!我們的插件需要做的只是實現程序定義的接口。主程序不需要知道插件怎樣實現預定的功能,它只需要通過接口訪問插件,並提供主程序相關對象的接口。這樣一來,主程序與各插件之間的信息交流就變得異常簡單。並且,插件對於主程序來說是完全透明的。

  3. 決策

  C# 是面向對象的程序設計語言。它提供了 interface 關鍵字來直接定義接口。同時, System.Reflection 命名空間也提供了訪問外部程序集的一系列相關對象。這就為我們在 C# 中實現插件構架打下了堅實的基礎。

  下面,我們將以一個具有插件構架的程序編輯器為例,來闡述這種構架在 C# 中的實現。

  二、設計過程

  好了,現在我們准備把所有的核心代碼都放在 CSPluginKernel 命名空間中。用VSIDE建立一個C#類庫工程。在命名空間 CSPluginKernel 中開始我們的代碼。

  1. 接口設計

  我們的程序編輯器會向插件開放正在編輯的文檔對象。程序啟動後,就枚舉每一個插件並把它連接到主程序,同時傳遞主程序對象的接口。插件可以通過這個接口來請求主程序對象或訪問主程序功能 。

  根據上面的需求,我們首先需要一個主程序接口:

  

public interface IApplicationObject {
  
          void Alert( string msg ); // 產生一條信息
  
          void ShowInStatusBar( string msg ); // 將指定的信息顯示在狀態欄
  
          IDocumentObject QueryCurrentDocument(); // 獲取當前使用的文檔對象
  
          IDocumentObject[] QueryDocuments(); // 獲取所有的文檔對象
  
          // 設置事件處理器
  
          void SetDelegate( Delegates whichOne , EventHandler targer );
}
// 目前只需要這一個事件
public enum Delegates {
  
          Delegate_ActiveDocumentChanged ,
}
   
          然後是 IDocumentObject 接口。插件通過這個接口訪問編輯器對象。
///
/// 編輯器對象必須實現這個接口
///
public interface IDocumentObject {
  
          // 這些屬性是 RichTextBox 控件的相應的屬性映射
  
          string SelectionText { get ; set ; }
  
          Color SelectionColor { get ; set ; }
  
          Font SelectionFont { get ; set ; }
  
          int SelectionStart { get ; set ; }
  
          int SelectionLength { get ; set ; }
  
          string SelectionRTF { get ; set ; }
  
          bool HasChanges { get ; }
  
          void Select( int start , int length );
  
          void AppendText( string str );
  
          void SaveFile( string fileName );
  
          void SaveFile();
  
          void OpenFile( string fileName );
  
          void CloseFile();
}

  • 首頁
  • 上一頁
  • 1
  • 2
  • 下一頁
  • 尾頁
  • 共2頁
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved