2010-08-13 30 views
2

我正在構建一個應用程序,該應用程序使用抽象工廠模式來允許運行時確定我的IHardwareDevice的哪個子類根據它如何響應標識請求來創建。我可能會創建Hardware1或Hardware2。IoC的中斷鏈

問題在於我想在這些IHardwareDevice對象中使用狀態模式,並且我想讓IoC容器創建狀態。沒有直接調用IoC容器來解決用於保存IHardwareDevice的狀態對象的方法嗎?

或者,我是否以錯誤的方式思考這個問題?因爲我的Factory幾乎是這個庫的入口點,可以讓這個Factory處理實例化在庫中使用的容器嗎?我打算讓客戶端應用程序實例化容器,然後使用它來訪問它所需的庫的任何部分,例如工廠。

我打算使用Windsor作爲IoC容器,但是在項目的早期階段需要切換。

+0

你的意思是「我希望國家是由IoC容器創建的」? – 2010-08-14 05:50:15

+0

這意味着我需要State對象可能必須由IoC容器滿足的任何依賴關係,而不是讓Factory實例化它們並將它們傳遞給State對象。 – Darran 2010-08-14 11:24:33

回答

0

溫莎具有自動實現抽象工廠一個非常強大的工具 - Typed Factory Facility

它在很大程度上約定爲主,如果默認約定不適合您的需求,您可以通過提供覆蓋它定製ITypedFactoryComponentSelector

它使您可以訪問所有可能需要做出決定的信息 - 您想要沿調用通道傳遞哪些內聯參數,以及要解析的組件。

2

大多數IoC容器(包括Windsor)都可以選擇將顯式依賴項(參數)傳遞給已解析依賴項的構造函數;當您撥打Resolve方法。

所以是的,你可以將你的State對象顯式地傳遞給你正在解決的IHardwareDevice實例。

+0

理想情況下,我想避免直接引用容器並從我的庫中調用Resolve。我將嘗試使用Typed Factory工廠,如果這對我不起作用,將會回退此選項。謝謝! – Darran 2010-08-14 11:44:07

3

這裏有一種方法可以與Autofac 2.2(http://autofac.org)來完成:

首先,枚舉狀態(使一些可能值)來區分:

public enum DeviceState { Online, Offline } 

然後,狀態的實現,如:

public class OnlineState : IDeviceState { } 

接下來,註冊每個狀態與其相應的枚舉項:

var builder = new ContainerBuilder(); 
builder.RegisterType<OnlineState>().Keyed<IDeviceState>(DeviceState.Online); 
builder.RegisterType<OfflineState>().Keyed<IDeviceState>(DeviceState.Offline); 
// Register other components here 

最後,硬件設備使用索引來選擇狀態。 IIndex的實現由容器自動提供:

public class Modem : IHardwareDevice 
{ 
    IIndex<DeviceState, IDeviceState> _states; 
    IDeviceState _currentState; 

    public Modem(IIndex<DeviceState, IDeviceState> states) 
    { 
     _states = states; 
     SwitchOn(); 
    } 

    void SwitchOn() 
    { 
     _currentState = _states[DeviceState.Online]; 
    } 
} 

希望這會有所幫助。

尼克