2009-11-24 57 views
3

我有一個場景,我希望有n個類可以查看相同的數據並確定是否需要完成任何工作。工作由團隊完成,多個團隊可以同時處理數據。我正在考慮爲每個將實施CreateWork界面的團隊創建一個班級。所有CreateWork類都必須有發言權。目前只有少數,但未來還會有更多。如何在.net中查找程序集中特定接口的所有類.net

我的計劃解決方案

For each CreateWork class in assembly 
    class.CheckAndCreateWork(dataIn,returnedCollectionOfWorkToBeDone) 
Next 

須藤代碼是否有可能在一個優雅的方式做到這一點的一種設計模式?看起來有點凌亂來循環組件中的每個類。

乾杯

回答

9

你可以做到以下幾點:

  1. 使用Assembly.GetTypes獲取在裝配中定義的所有類型。要獲取代碼正在運行的組件的參考,請使用Assembly.GetExecutingAssembly

  2. 對於每種類型,請檢查它是否通過使用Type.IsAssignableFrom來實現所需的接口。

  3. 對於每種適當的類型,請使用Activator.CreateInstance創建一個實例。

這將是大約是這樣的(未測試):

foreach(var type in Assembly.GetExecutingAssembly().GetTypes()) { 
    if(typeof(ITheInterface).IsAssignableFrom(type)) { 
     var theInstance=(ITheInterface)Activator.CreateInstance(type); 
     //do something with theInstance 
    } 
} 
+0

+1。我*相信* IsAssignableFrom'比GetInterfaces()慢,Contains(type)'(只適用於接口)。但我可能是錯的。 – 2009-11-24 10:14:14

+0

我通常更喜歡IsAssignableFrom,因爲它涵蓋的範圍不僅僅是接口實現,例如它可以告訴您A類是否繼承B類。 – Konamiman 2009-11-24 10:21:07

+4

IsAssignableFrom是要走的路,GetInterfaces返回僅在當前類型上定義的接口,但不檢查接口繼承(IBar:IFoo)。通過發佈所有類型的接口鏈,csc簡化了這一點,但並非所有編譯器都這樣做。 – 2009-11-24 10:21:40

0

這是一個標準的插件任務。那裏有很多實現。如果你已經加載了你的assemby,找到你感興趣的類型很容易 - 你需要使用方法assemlby.GetExportedTypes()Activator.CreateInstance()(假設你有無參數的構造函數 - 否則你可能希望使用容器來注入依賴並建立你的工作實例)

對於簡單的情況下,這已經足夠:

var workerTypes = assembly.GetExportedTypes() 
    .Where(t => t.IsClass && !t.IsAbstract && typeof(IWorker).IsAssignableFrom(t)); 

foreach (var type in workerTypes) 
{ 
    var worker = (IWorker)Activator.CreateInstance(type); 
    worker.CheckAndCreateWork("Work"); 
} 

獲取和裝載assemlby是另一個話題。您可以在運行時要麼使用負載或Assemlby.LoadFrom()靜態鏈接到您的應用程序並使用這樣的事:

var assembly = typeof(SomeClassInTargetAssembly).Assembly; 

動態加載可以通過所有* .DLL文件在特定目錄中列舉完成(例如,./plugins)是這樣的:

​​3210

您可能要分開運行工人裝載的流程,以避免裝載工人類型的多次(如果你需要在應用程序生命週期運行工不止一次)

1

我認爲你應該使用裝飾模式。

相關問題