2010-05-07 102 views
9

我想要實現插件式應用程序。我知道現在已經有幾種解決方案,但這只是對這個概念的證明,沒有其他。這個想法是讓應用程序的主應用程序在默認情況下幾乎沒有特色,然後讓插件相互瞭解,讓它們實現所有需要的功能。.NET中的插件式體系結構

幾個問題就出來了:

  1. 我想在運行時的插件來了解對方,通過我的申請。這並不意味着在代碼時他們無法引用其他插件的程序集,因此他們可以使用它的接口,只有插件功能初始化應該始終通過我的主應用程序。例如:如果我既加載了插件X,又加載了Y,並且Y想要使用X的功能,則應該通過我的應用程序使用它的功能來「註冊」它的興趣。我必須在我的應用程序中有一種「字典」,用於存儲所有已加載的插件。在註冊我的應用程序的興趣後,插件Y會獲得對X的引用,以便它可以使用它。這是一個好方法嗎?
  2. 當編碼使用X的插件Y時,我需要引用X的程序集,所以我可以對它的接口進行編程。這有版本控制的問題。如果我將我的插件Y編碼爲插件X的過時版本,該怎麼辦?我是否應該始終使用所有組件的「中心」位置,總是有組件的最新版本?

有沒有偶然的機會找到那些專門針對這些.NET設計的書?

感謝

編輯:我認爲人們漂離我做了2個問題了。我可以看一下MEF和#develop,但我想詳細解答我提出的問題。

+8

我建議尋找MEF,這是全新的,但看起來很有希望。 – 2010-05-07 21:50:22

+2

@馬特 - 想你應該把這個作爲一個答案 - 這正是我要說 – 2010-05-07 21:51:13

+1

我已經聽到了MEF的,但是作爲OP說,我的想法是不使用已建成的框架,但落實它自己。它不需要非常複雜的東西。 – 2010-05-07 21:52:02

回答

3

調查System.AddIn命名空間。它比MEF稍低一點,所以應該給你「正在實施它」的經驗,你正在尋找。

+1

有用的鏈接:[MEF vs AddIn](http://stackoverflow.com/questions/835182/choosing-between-mef-and-maf-system-addin)和[MSDN System.AddIn](http:// msdn。 microsoft.com/en-us/library/gg145020(v=vs.100).aspx) – 2012-10-12 15:43:49

1

一旦我完成它使用this example。我喜歡它,但幾年前,我想現在可能會有更好的解決方案。只要我記得基本的想法是在你的程序中有抽象類,並且你的插件繼承那個類並編譯爲DLL ......或者使用Interfaces類似的東西。無論如何,這種方法對我很好。後來我添加了一個filesystemwatcher,這樣它可以在運行時加載這些DLL插件。

To load an Assembly

To get the types the assembly exposes

+1

正是我要說的。添加了一些感興趣的MSDN頁面的鏈接。 – Skizz 2010-05-07 22:25:35

+0

是的,但這是一個簡單的例子。只是基本的反思和簡單的OO設計。 – 2010-05-08 03:25:39

+0

是的,這是......我唯一的理由是因爲它能夠解決你上面指定的問題......當然,你需要編寫複雜的插件管理器。如果你正在尋找一些開箱即用的東西,那麼就像MEF一樣,像所有人一樣建議......它似乎非常強大。 – m0s 2010-05-08 06:38:49

2

有一本好書,打造你在找什麼:剖析C#應用程序:內部SharpDevelop的。這裏有一個鏈接:http://www.icsharpcode.net/OpenSource/SD/InsideSharpDevelop.aspx

SharpDevelop應用程序完全基於插件,本書講述了他們如何構建它,他們面臨的陷阱以及他們如何克服它。這本書可以從網站免費獲得,或者你也可以購買。

6

我建議您考慮一下MEF。這是一種在.NET中執行插件的新方法。例如,這是推薦用於VS2010的新插件的方式。我自己並沒有使用它,但是我對它的看法很好看。添加此爲別人:)

+0

請參閱http://stackoverflow.com/questions/835182/choosing-between-mef-and-maf-system-addin。 MEF不是創建加載項的框架。 – cdiggins 2013-01-06 23:17:05

0

關於你暴露了兩個具體問題的敦促下一個答案:

1)我不知道什麼是你想實現的,但我的猜測是,你想擁有功能的延遲初始化,以及延遲加載插件。如果這是目標,那麼你提出的建議可能會起作用。所以它可以像這樣工作:

  • Y插件提供了它需要使用的功能列表(可以通過特定的接口實現或通過xml清單來完成)。
  • 的X外接實現其允許初始化的特徵,與像初始化(FEATUREID)的方法的API。
  • 主機應用程序獲取由Y所需要的功能列表,加載/初始化X插件,並呼籲初始化每個功能。
  • 主機應用程序還提供了一種GetFeature()方法其中Y可以用它來得到一個「功能」對象,這將在X.實施

但是參考,如果插件Y具有直接訪問X API,我認爲沒有必要擁有所有用於註冊功能的基礎架構。 Y可以通過直接使用X API來訪問X特性,並且在需要時Y會照顧每個特性的懶化初始化。例如,Y可以調用SomeXFeature.DoSomething(),並且該類的實現將在首次使用該特性時初始化該特性。

2)如的組件改變的API,任何組件取決於它可能會斷裂。插件只是依賴於其他程序集的程序集,所以它們也會中斷。以下是一些可以減輕這個問題的方法。

  • 分配一個版本號的每個插件。這可能只是程序集版本。
  • 當加載插件,確保所有的依賴性可適當滿足(即,它依賴必須存在和所需版本的所有插件)。拒絕加載插件,如果不能滿足依賴關係。
  • 實現插件管理工具,用於所有插件安裝/卸載操作。當試圖安裝不滿意的依賴性插件時,或試圖卸載其他插件所依賴的插件時,管理器可以檢查依賴關係並報告錯誤。

Mono.Addins框架使用了類似的解決方案。在Mono.Addins中,每個加載項都有一個版本號以及它所依賴的加載項/版本列表。加載加載項時,加載項引擎可確保加載具有正確版本的所有相關加載項。它還提供了用於管理加載項安裝的API和命令行工具。