以下是示例代码:
public interface IService<TEntity> {
IContext Context { get; set; }
//unimportant methods
bool Validate(TEntity entity);
void Add(TEntity enttity);
}
public class UsersController : Controller {
private IService<User> _service;
public MyController(IService<User> service){
_service = service;
_service.Context = ControllerContext;
}
}
我正在使用AutofacControllerFactory在我的ASP.NET MVC应用程序中创建控制器。 是否可以在每个控制器的构造函数中消除这行代码:
_service.Context = ControllerContext;
换句话说:是否可以使用ControllerContext自动设置此属性? 它应该是可能的,因为每个IService实现都有一个可设置的IContext属性。
我应该扩展AutofacControllerFactory还是有一种标准的doint方法?
答案 0 :(得分:2)
你所拥有的是循环依赖。
UsersController
取决于IService<User>
IService<User>
取决于ControllerContext
ControllerContext
取决于UsersController
没有DI容器可以进入你班级的内部并控制那里发生的事情。他们可以为您设置依赖关系,并从外部将它们注入到您的类中。但是,它们不能很好地处理循环依赖,因此更好的选择是重新设计API。
从这里看起来非常像IService<TEntity>
的Context属性是 Leaky Abstraction 。服务不需要知道运行它的UI框架。
您通常可以通过将其中一个消费者更改为更强大的事件驱动体系结构来打破循环依赖。
这是an article about this sort of problem。
这是一个与你的MVC问题相似的答案:Is there a good/proper way of solving the dependency injection loop problem in the ASP.NET MVC ContactsManager tutorial?