我如何使用Ninject为我的UnitOfWork添加一个服务层
本文关键字:一个 服务 添加 何使用 Ninject UnitOfWork 我的 | 更新日期: 2023-09-27 18:07:32
我在尝试设置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 code: Bind<IUnitOfWork>().To<UnitOfWork>().InRequestScope();
这实际上工作得很好。然而,我想改变它,使它不是包含存储库,而是包含多个存储库的服务。
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来实现我想要的呢?
对不起,这真是一个过分的评论,但是嘿…
DbContext
是一个工作单元,创建一个跨两个DbContexts的巨型工作单元绝对不是一般模式(因此你的问题是你)
对一个相关问题的回答的评论也进入了同样的领域。
在尝试用这种方法解决问题之前先问自己几个问题:
- 除了拥有DbContext之外,你想用我的这个工作单元完成什么?
- 这需要是事务性的吗?
- 中间是否有一个缺失的服务,它应该有自己的数据来引用其他两个服务?
- 这需要跨越两个有界的上下文吗?如果以后你需要把它们拆开怎么办?
- 如果我在我的应用程序中有3个这样的情况,我会把它们合并到一个BC中吗?4?
对我来说,关键是创建自己的UoW来包装UoW:
- 买不到什么
- 让你更难理解你的核心问题
如果你仍然想把这些东西硬塞进Ninject,技术上的方法是同时使用上下文保存和工厂扩展——去阅读他们的wiki中的例子。如果你决定剥离一些东西,它们可能还有部分可以发挥作用。
更新:我现在明白你的意思了——链接到这样的东西是很重要的,它可以预先引导你的思维。首先,去看看这个。接下来,决定你是否要有一个工作单元。如果是这样,谁和在哪里提交和处理它?
如果存储库和/或服务要共享UoW或DBContext,并且要集中提交东西,那么您绑定要共享/处置的东西在requestscope中有它a)获得单个共享实例b)获得处置
我主要关心的是是否所有这些抽象实际上都有好处——你是否真的在编写使用抽象的测试(而不仅仅是前几个)?你真的要换仓库吗?我个人会去读几遍DDD的书,作为更好的时间投资。
我意识到很多这是高度傲慢的,这只是一个简化的问题,代表了一个更大的问题的一部分,但是我最近看到太多的问题是由包装层和DI容器欺骗的交叉引起的,因此我的咆哮。咆哮完成,谢谢!