我尝试设置DI时遇到了一个小路障。
因为我有这个控制器:
public UsersController(IUnitOfWork unitOfWork)
{
// Stuff
}
我之前有这个UnitOfWork实现直接访问我的存储库。
public class UnitOfWork : IUnitOfWork, IDisposable
{
private readonly DbContext _context = new DbContext();
public IRepository<User> Users { get { return new UserRepository(_context); } }
}
Ninject UnitOfWork代码:Bind<IUnitOfWork>().To<UnitOfWork>().InRequestScope();
现在这实际上运作正常。但是我想更改它,以便包含存储库的UnitOfWork,而不是包含多个存储库的服务。
public class UserService : IUserService
{
private readonly IUserRepository _userRepository;
public UserService(IUserRepository userRepository, /* Other repositories */)
{
_userRepository = userRepository;
}
}
现在我能想出的唯一解决方案是
public class UnitOfWork : IUnitOfWork, IDisposable
{
private readonly DbContext _context = new DbContext();
public IUserService UserService
{
get
{
return new UserService(new UserRepository(_context), /* etc. */);
}
}
}
这似乎不对。现在我自己创建所有服务依赖项。
我在StackOverflow上看过帖子,提到让服务访问多个存储库并处理业务逻辑而不是让控制器(MVC应用程序)担心它会更好。
无法找到有关如何正确执行此操作的任何细节。那么我怎么能用Ninject来做我想要的事呢?
答案 0 :(得分:2)
对不起,这真是一个杂乱无章的评论,但是嘿......
DbContext
是一个工作单元,创建一个跨越两个DbContexts的怪物工作单元绝对不是一般模式(因此你的问题就是你)
对此answer here to a related question的评论偏离同一领域。
在尝试以这种方式解决之前要问自己的问题:
对我而言,关键在于创建自己的UoW来包装UoW:
如果您仍然想要使用Ninject来解决这个问题,那么技术方法是同时使用Context Preservation和Factory Extensions - 请阅读其wiki中的示例。如果你决定剥离东西,他们可能还有部分可以玩。
更新:我现在抓住你的漂移 - 重要的是链接到预先指导你思考的东西。首先,阅读this。接下来,决定你是否有一个工作单元。如果是这样,谁将在哪里提交并处理它?</ p>
如果存储库和/或服务要共享UoW或DBContext,而某些东西将集中提交,那么您将要共享/处置的内容绑定到InRequestScope中以获取它a)获取单个共享实例b)获得处置
我主要担心的是,所有这些抽象是否真的有益于事物 - 您是否真的在编写使用抽象的测试(而不仅仅是前几个)?你真的要切换存储库吗?我个人会多次阅读DDD书作为更好的时间投资。
我意识到很多这是非常光顾的,这只是一个简单的问题,代表了一个更大的问题的一部分,但我刚刚看到太多的问题,最近由包装层和DI容器欺骗的交集提示,因此我的咆哮。完R,谢谢!