让我有两个非常基本的对象,如:
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));
)。在这种情况下,你会如何注入依赖?
答案 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可以在您设置正确的属性时自动为您执行此操作)。