具有循环依赖性的依赖注入

时间:2011-10-05 09:41:13

标签: c# dependency-injection inversion-of-control

让我有两个非常基本的对象,如:

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;
    }
}

后来我决定通过DI将View对象注入Controller,但我有一个循环依赖(即我不能使用var ctrl = new Controller(new View(ctrl));)。在这种情况下,你会如何注入依赖?

3 个答案:

答案 0 :(得分:4)

最常见的解决方案是使用依赖项属性来解决循环依赖关系。即在其中一个类中创建一个新属性,并让IoC容器分配它。

如果您使用的是Unity,则应将[Dependency]添加到该属性中。

旁注:视图不应该依赖于控制器。它根本不应该意识到这一点。

更新回复评论

你做不到。这是循环依赖的问题。唯一的其他解决方案是使用组合。那就是将常用功能分解为一个单独的类,并将其包含在控制器和视图中。

答案 1 :(得分: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框架。

答案 2 :(得分:0)

使用构造函数注入完全不能这样做 如果将控制器的构造函数更改为

public Controller(IView view)

您将以哪种顺序创建两个对象? View需要控制器实例,控制器需要视图。 但是,您可以将控制器的IView属性设置为public,并在创建后设置Property(有些DI-Containers可以在您设置正确的属性时自动为您执行此操作)。