2009-12-09 79 views
2

我正在使用C#插件體系結構。插件是DLL的暴露一堆演示者,這是實現IPresenter接口的對象。 IPresenter接口可在所有插件共享的DLL中使用。演示者還可以實現IAction接口定義的其他方法,如ILoadAction,ISaveAction等。這些接口也由同一個DLL共享,因此所有插件都可以具有實現此類接口的演示者。插件體系結構和共享接口問題

案例:我在插件A中有演示者X,它實現了IPresenter接口和ILoadAction接口。在插件B中,我要求插件架構給我一個演示者X.這給了我一個對象IP地址 IPresenter。要調用該演示者的LoadAction方法,我必須將演示者轉換爲ILoadAction。

問題:如果我從插件A中的演示者X中刪除ILoadAction,插件B中的代碼仍將編譯,即使演示者不再實現ILoadAction。在這種情況下,我想要被編譯器警告。其實,我想避免不得不一直施展到某個IAction ...

問題:如何處理?

回答

0

兩個選項:

  1. 檢查對象(使用「爲」),而不是僅僅鑄造它(並更新你的程序邏輯來處理的情況下對象沒有實現的接口)
  2. 添加一個到你的共享DLL的接口,允許一個插件通知其他的功能,並提供強類型的方法來獲得各種接口的實現。所有插件都應該實現這個接口,並使用它的方法來獲得對其他插件中的功能的引用。
+0

這些選項實際上不會產生編譯時錯誤,如果你刪除該接口爲您的問題描述,但這決不是因爲整點編譯時錯誤你的插件方法似乎是插件沒有明確地耦合到其他功能,但可以有'額外的方法'。 如果你想編譯時間檢查:只是強制所有插件實施ILoadAction ... – 2009-12-09 10:44:25

+0

-1這聽起來不像一個可擴展的體系結構。想象一下,在開發了數百個實現之後,您現在需要添加另一個「功能」。這意味着在界面中添加另一種方法,從而破壞數百個實現。 – 2009-12-09 10:46:35

2

恐怕編譯器不會幫你在這裏。插件A可以在構建B之前,之中或之後隨時更改,因此插件體系結構需要應對可能的接口丟失 - 要麼爲接口返回空值,要麼拋出異常。

至於正確類型的獲取項目,這可以來達到的使用泛型:

T IPresenter.GetAction <T> where T : class, IAction() 
{ 
    return (T) GetAction (typeof T) 
} 

所以中投在的getAction方法完成,而不是調用者(排序):

var action = PluginA.GetAction <ILoadAction>(); 

編輯:

如果調用做<>實在是太多了,試試:

bool GetAction<T> (out T a) where T : class, IAction 
{ 
    // stuff 
    return interface_found; // or throw an exception? 
} 

然後,你可以這樣做:

ILoadAction action; 
if (!PluginA.GetAction (out action)) 
{ 
    // failed to get interface! 
}