2010-06-10 68 views
2

有沒有使用IoC,MEF [Imports]或另一個DI解決方案在對象創建時而不是在組合時間期間編寫依賴關係的方法?IoC - 對象實例的動態組合

這是我目前的想法。如果您有一個引發事件的對象實例,但您沒有創建對象並將其保存在內存中,則每次創建對象時都必須註冊事件處理程序。據我所知,大多數IoC容器都要求你註冊組合中使用的所有類,並調用Compose()來使它掛鉤所有的依賴關係。

我認爲這可能是一個可怕的設計(我正在處理一個遺留系統)這樣做是因爲對象創建,依賴注入等的開銷......但我想知道是否有可能使用一個突發的IoC技術。

也許我有一些術語混合起來,但我的目標是避免寫了一個框架對象的實例爲「鉤出來的事件」,並使用類似MEF爲[出口]處理程序(依賴),其堅持一個非常具體的接口和[ImportMany]他們到一個對象實例,所以我的出口被調用,如果應用程序啓動時程序集在那裏。所以也許所有的對象仍然可以在應用程序啓動時組成,但我希望系統在創建和銷燬對象時查找並調用所有對象。

回答

4

通常,您在DI/IoC環境中處理即時實例的方式是使用抽象工廠。工廠僅允許允許與容器直接交互的類的類型,以便在實例化新對象時解決依賴關係。

public interface IWidgetFactory 
{ 
    IWidget CreateWidget(...); 
} 

public class MyIocWidgetFactory : IWidgetFactory 
{ 
    private IoCContainer container; 

    public MyIocWidgetFactory(IoCContainer container) 
    { 
     if (container == null) 
      throw new ArgumentNullException("container"); 
     this.container = container; 
    } 

    public IWidget CreateWidget(...) 
    { 
     // Assumes that the container is configured to create transient objects 
     // for IWidget, not a singleton. 
     return container.Resolve<IWidget>(); 
    } 
} 

請不要混淆這與服務定位器反模式;沒有其他任何東西被允許觸摸容器,只是工廠,它只創建一種類型的對象。

此時,您只需傳遞IWidgetFactory即可滿足在運行時創建小部件的任何需求。就是這樣 - 你一直在維護DI。

+0

一些DI容器也支持爲您生成工廠。你可以注射例如Func -delegate。 DI容器然後爲IWidget實例生成一個工廠。 例如在Autofac中:http://nblumhardt.com/2010/01/the-relationship-zoo/ – Gamlor 2010-06-13 21:53:30

+0

我很好奇,您是否需要將此工廠注入想要在第一個對象中創建對象的類地點?或者這是否需要實例化? – stuartmclark 2013-02-06 13:58:52

+1

@stuartmclark:你注入工廠。這就是爲什麼它是'IWidgetFactory'而不是某種具體類型。幾個IoC容器實際上能夠自動生成工廠,所以你甚至不需要上述類型,你可以注入'Func '或'Lazy '。 – Aaronaught 2013-02-07 01:15:58