我想知道什麼,一般的建議是(屬性,接口,抽象類,或它們的組合)以下實現:屬性,接口或抽象類
/// <summary>
/// Loads class specific information into a list for serialization. The class must extend PlugIn.
/// The filenames parameter is passed from a FileDialog.
/// </summary>
/// <param name="filenames">Accepts any number of filenames with fully qualified paths.</param>
public static void ExtractPlugInData(params string[] filenames)
{
List<Type> l;
foreach (string f in filenames)
{
Assembly a = Assembly.LoadFrom(f);
// lambda expression selects any class within a library extending the abstract PlugIn class
l = a.GetTypes().Where(type => typeof(PlugIn).IsAssignableFrom(type)).ToList<Type>();
if (l.Count > 0)
// write data to serializable class
WritePlugInData(f , l);
else
// throw exception
WriteLine("{0} :: No PlugIn Data Found" , a.FullName);
}
}
我知道有優勢,每種方法的缺點。顯然,屬性需要一些反映(如抽象擴展和接口實現一樣)。一個抽象類需要我們唯一的基礎繼承,並且接口中的任何未來更改都可能會破壞任何現有的插件。所以,正如我所看到的那樣,這些都是缺點。
性能不是問題(除非有一些我沒有看到),因爲在提取一個合格的類中的任何反射只進行一次。要保存的關鍵數據是插件名稱(「MyPlugIn」),名稱空間(「SuperPlugIn.PlugInClass」)以及.dll的啓動路徑。現在,通過抽象PlugIn類,強制實現了屬性的擴展。如果我們實現一個接口(IPlugIn),這或多或少是相同的結果。
我們允許最終用戶編寫自定義插件。通過我們內部編寫的插件,可以很容易地爲我們的應用程序教授和執行一個必需的結構來實例化一個合格的類。但是,我也在考慮如果最終用戶發生重大變化,那麼困難或不便。
歡迎發表評論,建議和問題!
注意:要感謝喬恩斯基特在片段中的lambda表達式。 :)
編輯:我應該在這個旨在成爲獨立於平臺(即單聲道)開始所提到的。
UPDATE:基於優秀的建議,意見和下面的鏈接,屬性和接口的組合是最好的辦法。通過屬性可以加載程序集並相當安全地檢查所需的信息和實現,而無需實例化插件類/對象。在允許第三方或最終用戶創建自定義插件的情況下,這非常理想。我們可以檢查以確保合適的合同實施在屬性表明它應該是的地方。我們可以檢查所需的依賴關係和資源,並在任何實例之前提醒開發人員任何問題。
我很確定它不會是一個接口。 – Jay 2010-01-26 03:44:32
Aaronaught給出的許多參考文獻最終都使用了接口。令人驚訝的是,Mono.Addins(http://www.mono-project.com/Mono.Addins)去了屬性路由。 – IAbstract 2010-01-26 05:11:15
的確如此,這就是爲什麼我最初用「幾乎」這個詞限定我的答案的原因。 ;)沒有*正確的*或*錯誤的*答案,你甚至可以將兩種方法結合起來(使用屬性來查找類,但仍然有實現插件接口)。 – Aaronaught 2010-01-26 05:41:13