2009-11-18 80 views
5

一旦解決了加載插件的問題(在.NET中通過MEF出現的情況),下一步要解決的就是與它們的通信。簡單的方法是實現一個接口並使用插件實現,但有時插件只需要擴展應用程序的工作方式,並且可能有很多擴展點。擴展/插件通信的體系結構

我的問題是關於如何處理該擴展點。我見過這樣做,不同的方式,但我不知道每個人的優點和缺點,如果有更多更好的方式來做到這一點:

  • 活動:添加靜態事件,所有的東西我們想讓「可擴展」。例如,如果我想爲User類添加自定義驗證,則可以添加一個OnValidation靜態事件處理程序,並在構建時從該插件向它添加事件。
  • 信息:有一個公共汽車和一條消息。插件可以訂閱特定的消息,並在其他類發佈該消息時進行操作。消息應該包含插件可以工作的上下文。在驗證情況下,邏輯層將發佈UserValidation消息,並且插件將在接收到消息時採取行動。
  • 接口:主機應用程序負責調用實現某些接口的所有插件,併爲它們提供當前操作的上下文。在驗證的情況下,插件可以使用Validate(對象上下文)方法實現IValidator或IUserValidator。

你曾經使用過某種暴露的方法嗎?哪一個最適合你?

在您提出問題之前,我們的應用程序是一個可擴展的核心(用戶,rola和內容管理),用於構建以客戶端爲中心的Web應用程序。構建在ASP.NET MVC上的所有東西。

回答

2

您的設計決策的一個關鍵是要分析並清楚瞭解插件將來自於彼此的不同之處。

E.g.當處理靜態事件時,您可能必須將每個事件定義爲某種形式的令牌,枚舉,對象等。必須爲每個插件定義一組新事件自然會違背整個設計,特別是在鬆散耦合和重用。

如果你的插件是非常不同的從具有在這種情況下,因爲你的總線/通訊架構可能引起通信交換,該插件可以訂閱域/類別你可能會受益。即一系列事件和消息可能處於某個感興趣的領域。請注意,某個類別內的通信仍然可以使用靜態事件,因此這兩個替代方案並不相互排斥。

插件實現的直接接口在我的經驗中是最爲嚴格的插件體系結構。擴展插件接口通常意味着在插件和提供者處修改代碼。您需要有一個可靠的通用界面,您知道您的應用程序可以長期存在。

它可能會更容易被分解爲兩個方面爲你處理與設計 - 溝通渠道協議。靜態事件處理是一個協議問題,而總線消息傳遞和直接接口是一個通道問題。

通常我會說,協議是最難從一開始就正確設計的,因爲您可能沒有一個牢固的感覺來確定您可以繪製線條的一般或特定程度。

編輯:拉斯取得了他的評論很重要的一點 - 如果你的平臺支持例外,您可以使用直接接口時集中了大量的錯誤處理,不必處理是通用的,也許是錯誤的緩解插件outisde他們的特定領域(例如「插件加載錯誤」或「文件打開失敗」)。但是,如果每次添加插件時都必須維護接口,這些好處似乎會消失。最糟糕的情況是當接口開始變得不一致時,因爲你從一開始就沒有意識到他們應該支持什麼。當已經構思出大量插件時重構整個界面設計並非易事。

+0

接口可能是我的方法,雖然它取決於應用程序和它的插件需求。 但是這是一個非常乾淨的插件方法,並且也很容易從插件中分離出異常。 – 2009-11-18 12:53:23

0

我願意跟觀察者模式。從GOF:

定義對象間的一種一對多的依賴 這樣,當一個 對象改變狀態的所有其 家屬得到通知並自動更新 。

也被稱爲發佈 - 訂閱我會建議它在您的示例中最接近地匹配案例二。

+0

恕我直言,觀察員模式是從這個問題的一個層面。即他提出的所有替代方案都適合這種模式。當前的問題與觀察者模式的具體實施決定有關。 – sharkin 2009-11-18 12:53:13

+0

在再次閱讀和進一步消化時,我認爲你可能是正確的R.A. – Martin 2009-11-18 14:11:44