2010-08-03 89 views
4

經過對收到我的previous question about modeling my code to maximize code re-use的所有重要答案的反思之後,我開始想知道是否可以在運行時將接口分配給對象,而不是編碼時。是否可以在運行時將接口分配給對象?

舉個例子來說,從my previous question的代碼的簡化部分:

public class OutboxManager 
{ 
    private IVendorMessenger _VendorMessenger; 

    //This is the default constructor, forcing the consumer to provide 
    //the implementation of IVendorMessenger. 
    public OutboxManager(IVendorMessenger messenger) 
    { 
     _VendorMessenger = messenger; 
    } 

    public void DistributeOutboxMessages() 
    { 
     VendorMessenger.SendMessageToVendor() 
         _OutboxMgrDataProvider.MarkMessageAsProcessed(om) 
    } 

} 

目前,如果有人要消耗這一類,他們必須編寫實現IVendorMessenger類和初始化的過程中爲其提供參數:

var MyOutboxManger = new OutboxManager(new MyVendorMessenger()) 

如果不是對接口參數進行硬編碼,而是在運行時分配它,那該怎麼辦呢?這樣,我可以編譯一個實現IVendorMessenger的類的DLL,將它放到OutboxManagerExecutable所在的同一個文件夾中,並且它會在運行時將所有內容連接起來。我想,通過使用這個邏輯,我可以找到一種方法在相同的文件夾中放置多個IVendorMessenger的實現,並將可執行文件設計得足夠聰明,可以遍歷所有適當的dll並相應地使用它們。

.NET 4中可以使用這種類型的功能嗎?

+0

你是說你想利用沒有實現IVendorMessenger類,並在運行時插上就頂一下,接口它說它呢? – 2010-08-03 12:23:44

+0

@Lasse不,我想插入的任何類會假定'IVendorMessenger' – 2010-08-03 12:27:49

回答

4

查看Managed Extensibility Framework (MEF)。它可以自動組成你的應用程序的依賴關係,就像你描述的那樣。它隨.NET 4.0一起提供。

+0

我以前聽說過MEF,但我不確定它是否可以用來解決這類問題。我不知道它是什麼樣子使用。 – 2010-08-03 12:33:42

+0

@本:我鏈接到的網站上有很多例子。 – 2010-08-03 13:58:59

1

您是否想過使用MEF?它允許您創建許多模塊的應用程序構建。

你可以看到它here

+0

Ooops ..看起來像我是一個30秒太晚;) – 2010-08-03 12:25:58

1

編輯:我剛剛意識到,我誤解了這個問題。實際上,而不是這個問題似乎是在運行時爲對象分配接口,而是關於後期綁定類型名稱。

我會留下答案作爲社區Wiki,以防其他人有相同的誤解。


這通常被稱爲接口注入,並一直在爲願望清單CLI和JVM,只要他們都存在。特別是爲編程語言編寫實現的人,如JRuby,XRuby,Ruby.NET,IronRuby,IronPython,Jython,Rhino,IronJS等,本來不是爲CLI或JVM設計的,在他們的願望清單中,因爲這意味着他們不再需要維護並行類型層次結構,並在兩者之間來回編組對象。然而,他們似乎並不是很快或者甚至根本就不在眼前,儘管對於達芬奇機器來說,至少有一個JVM的吸管規格和相應的部分原型實現。

+0

örg謝謝你的迴應。我想我實際上正在尋找一種解決方式,以後期綁定的方式,但我不知道該怎麼說。關於你的回答,雖然,*接口注入*與*依賴注入*有什麼不同? – 2010-08-03 13:33:57

2

這是反射的一個非常常見的用例。在.NET API爲您提供您需要的作品:

  1. 找到了所有.dll的目錄中:Assembly.LoadFile()
  2. 迭代通過每個組件類型:Directory.GetFiles()
  3. 負荷運行時的組件: Assembly.GetTypes()
  4. 對於每種類型的,看它是否實現了你的接口:Type.IsAssignableFrom()
  5. 如果是的話,獲得並調用它的構造函數來創建一個:Type.GetConstructor()

之後,你有一個Object,你可以轉換爲IVendorMessenger並傳遞進去。

+0

這是一個非常有用的答案。非常感謝! – 2010-08-04 10:03:51

+0

您也可以將此答案標記爲已接受。 ;) – munificent 2010-08-04 20:58:45

相關問題