我如何使用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来实现我想要的呢?

我如何使用Ninject为我的UnitOfWork添加一个服务层

对不起,这真是一个过分的评论,但是嘿…

DbContext 是一个工作单元,创建一个跨两个DbContexts的巨型工作单元绝对不是一般模式(因此你的问题是你)

对一个相关问题的回答的评论也进入了同样的领域。

在尝试用这种方法解决问题之前先问自己几个问题:

  • 除了拥有DbContext之外,你想用我的这个工作单元完成什么?
  • 这需要是事务性的吗?
  • 中间是否有一个缺失的服务,它应该有自己的数据来引用其他两个服务?
  • 这需要跨越两个有界的上下文吗?如果以后你需要把它们拆开怎么办?
  • 如果我在我的应用程序中有3个这样的情况,我会把它们合并到一个BC中吗?4?

对我来说,关键是创建自己的UoW来包装UoW:

  1. 买不到什么
  2. 让你更难理解你的核心问题

如果你仍然想把这些东西硬塞进Ninject,技术上的方法是同时使用上下文保存和工厂扩展——去阅读他们的wiki中的例子。如果你决定剥离一些东西,它们可能还有部分可以发挥作用。

更新:我现在明白你的意思了——链接到这样的东西是很重要的,它可以预先引导你的思维。首先,去看看这个。接下来,决定你是否要有一个工作单元。如果是这样,谁和在哪里提交和处理它?

如果存储库和/或服务要共享UoW或DBContext,并且要集中提交东西,那么您绑定要共享/处置的东西在requestscope中有它a)获得单个共享实例b)获得处置

我主要关心的是是否所有这些抽象实际上都有好处——你是否真的在编写使用抽象的测试(而不仅仅是前几个)?你真的要换仓库吗?我个人会去读几遍DDD的书,作为更好的时间投资。

我意识到很多这是高度傲慢的,这只是一个简化的问题,代表了一个更大的问题的一部分,但是我最近看到太多的问题是由包装层和DI容器欺骗的交叉引起的,因此我的咆哮。咆哮完成,谢谢!