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框架。