2011-10-05 206 views
1

讓我有兩個非常基本的對象,如:依賴注入與循環依賴

public class View 
{ 
    public View(Controller controller) 
    { 
     // Use the model exposed by the controller here 
    } 
} 

public class Controller 
{ 
    private readonly IView view; 

    public Controller() 
    { 
     this.view = new View(this); 
    } 

    public Controller(View v) 
    { 
     this.view = v; 
    } 
} 

後來我決定要注入View對象爲通過DI控制器但是我有一個循環依賴(即我不能使用var ctrl = new Controller(new View(ctrl));)。在這種情況下,你會如何注入依賴項?

+0

你打算對一個控制器有多個視圖嗎? –

+0

只有一個。儘管如此,我試圖在這種情況下避免屬性注入。 –

+0

那麼爲什麼要添加DI分辨率來查看?視圖和控制器之間會有1:1的關係。對不起,我沒有看到它的重點。 –

回答

4

最常見的解決方案是使用依賴屬性來解決循環依賴。即在其中一個類中創建一個新屬性並讓IoC容器分配它。

如果您使用的是Unity,則應該將[Dependency]添加到該屬性。

旁註:視圖不應該對控制器有依賴性。它根本不應該知道它。在回答

更新評論

你不能。這是循環依賴的問題。唯一的其他解決方案是使用組合。這是將通用功能分解成單獨的類並將其包含在控制器和視圖中。

+0

是的,實際上視圖只使用控制器公開的模型(用於數據綁定),在這種情況下試圖簡潔。順便說一下,我試圖避免屬性注入(因爲依賴關係對類功能至關重要)。 –

+0

閱讀我的更新。 – jgauffin

+0

是的,你是對的,似乎我必須用prop-inj去。或另一種奇特的解決方案。 –

0

你不能這樣做,如果你改變了控制器來

public Controller(IView view) 

以何種順序將創建兩個對象的構造在所有構造函數注入 ? 視圖需要控制器實例,控制器需要該視圖。 但是,您可以將控制器的IView屬性設置爲公開,並在創建後設置屬性(某些DI容器可以在設置正確屬性時自動爲您執行此操作)。

1

我實際上使用Ninject找到了一個很好的解決方案。

public class Controller 
{ 
    private readonly View view; 

    public Controller(ViewModule viewModule) 
    { 
     using (IKernel kernel = new StandardKernel(viewModule)) 
     { 
      this.view = kernel.Get<View>(new ConstructorArgument("controller", this); 
     } 
    } 
} 

凡ViewModule是一個預配置Ninject模塊來解決特定的視角依賴關係(GUI,CLI等),這裏的小問題是,我現在依賴於特定的DI框架。