[英]Attribute, interface, or abstract class
我想知道以下實現的一般建議(屬性,接口,抽象類或其組合):
/// <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),這或多或少是相同的結果。
我們允許最終用戶編寫自定義插件。 使用我們內部編寫的插件,可以很容易地為我們的應用程序教授和實施一個必需的結構來實例化一個合格的類。 但是,如果出現重大變化,我也在考慮最終用戶的困難或不便。
歡迎所有評論,建議和問題!
注意:感謝Jon Skeet在片段中的lambda表達式。 :)
編輯:我應該在開始時注意到這是平台無關的(即Mono)。
更新:基於下面的優秀建議,評論和鏈接,混合屬性和接口是最好的方法。 通過屬性,您可以加載程序集並相當安全地檢查所需的信息和實現,而無需實例化插件類/對象。 這在允許第三方或最終用戶創建自定義插件的情況下非常理想。 我們可以檢查以確保正確的合同實施到位,其中屬性表示它是假設的。 我們可以檢查所需的依賴項和資源,並在實例化之前提醒開發人員任何問題。
您希望最終用戶編寫插件嗎? 除非你的最終用戶是程序員,否則我認為這不是一個好主意。
這次我會保持我的答案很短,因為這是一個相當 大的 honkin' 欺騙 :
插件體系結構幾乎總是涉及在公共程序集中實現特定接口的外部程序集中的類;
已有數十個 千篇一律的 .NET 插件實現,包括微軟自己的Managed Extensibility Framework 。 不要重新發明輪子。
編輯:對於Mono,請查看Mono.Addins 。
Assembly.GetTypes
是一個非常昂貴的調用,我會盡可能避免它。 (App啟動時間很重要)
更快的方法是(我沒有基准測試)一個程序集級屬性,可以像這樣使用:
[assembly: PluginClass(typeof(MyPlugin), more info)]
然后,您可以在Assembly
上調用GetCustomAttributes
,這可能比GetTypes
快得多。
使用LINQ:
filenames.SelectMany(f =>
Assembly.LoadFrom(f).GetCustomAttributes(typeof(PluginClassAttribute), true)
.Cast<PluginClassAttribute>()
.Select(a => a.PluginType)
).ToList();
我可能傾向於使用屬性。 使用元數據擴展基類系統正是它們的目的,並且說“這個類是一個插件”當然適合這個法案。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.