循环依赖注入
本文关键字:注入 依赖 循环 | 更新日期: 2023-09-27 18:10:33
让我有两个非常基本的对象,如:
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注入视图对象到控制器中,但我有一个循环依赖(即我不能使用var ctrl = new Controller(new View(ctrl));
)。在这种情况下如何注入依赖呢?
最常见的解决方案是使用依赖属性来解决循环依赖。例如,在其中一个类中创建一个新属性,并让IoC容器为其赋值。
如果你使用Unity,你应该将[Dependency]
添加到该属性。
旁注:视图不应该依赖于控制器。它根本不应该意识到这一点。
回复评论
你不能。这就是循环依赖的问题。唯一的其他解决方案是使用组合。这就是将公共功能分解成一个单独的类,并将其包含在控制器和视图中。
我发现了一个使用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框架
在构造器注入中根本不能这样做如果将控制器的构造函数更改为
public Controller(IView view)
以什么顺序创建这两个对象?视图需要控制器Instance,控制器需要视图。但是,您可以将控制器的IView属性设置为公共,并在创建后设置该属性(当您设置正确的属性时,一些di - container可以自动为您完成此操作)。