开发者

Dependency Injection with Cyclic Dependency

Let me have two very basic objects 开发者_如何学Pythonlike:

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?


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.


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.


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).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜