Dependency Injection with Cyclic Dependency

雨燕双飞 提交于 2019-12-11 06:25:18

问题


Let me have two very basic objects like:

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

Later I decide to inject View object into the Controller via DI but there I have a cyclic dependency (i.e. I can't use var ctrl = new Controller(new View(ctrl));). How would you go about injectin the dependency in this case?


回答1:


The most common solution is to use a dependency property to solve circular dependencies. i.e. create a new property in one of the classes and let the IoC container assign it.

If you are using Unity you should add [Dependency] to that property.

A sidenote: A View should not have a dependency to a controller. It should not be aware of it at all.

Update in reply to comment

You can't. That's the problem with circular dependencies. The only other solution is to use composition. That is to break out the common functionality into a separate class and include it in both the controller and the view.




回答2:


I actually found a nice solution using 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);
        }
    }
}

Where the ViewModule is a pre-configured Ninject module to resolve the particular view dependency (GUI, CLI, etc.) Minor problem here is that, I'm now dependent on the particular DI framework.




回答3:


You can't do that at all with constructor-injection If you change the constructor of the controller to

public Controller(IView view)

in which order would you create the two objects? View needs the controller Instance and the controller needs the view. However, you can make the IView Property of the controller public, and set the Property after creation (Some DI-Containers can do this for you automatically when you set the correct attribute).



来源:https://stackoverflow.com/questions/7659379/dependency-injection-with-cyclic-dependency

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!