如何在 C# 中对工作单元和存储库使用依赖注入? (不是基于网络的应用程序)

How do I use Dependency Injection with Unit of Work and Repositories in C#? (Not a web based App)

我看到很多关于这个主题的问题和答案,但是绝大多数都在处理 ASP.Net 或其他基于 Web 的应用程序以及称为 .InRequestScope 的东西。我还没有在 NinjectWindows Application.

中找到这个方法

我有通常的 Unit of Work (UoW) 和 Repository (Repo) classes 和接口,但我想将相同的 DbContext 注入两者,每次 UoW 是 DIContainer 的 运行。我的代码如下所示;

public class UnitOfWork : IUnitOfWork, IDisposable
{
    private readonly FinancialContext _context;

    private IAccountRepository _accountRepository;
    public IAccountRepository Accounts
    {
        get { return _accountRepository; }
    }

    UnitOfWork(IMyContext context, IAccountRepository accountRepository)
    {
        _context = context;
        _accountRepository = accountRepository;
    }

    public void SaveChanges()
    {
        _context.SaveChanges();
    }

    public void Dispose()
    {
        _context.Dispose();
    }
}

public class AccountRepository : Repository<Account>, IAccountRepository
{
    public AccountRepository(IMyContext context) : base(context) { }
}

DIContainer 拥有以下关联;

Bind<IUnitOfWork>().To<UnitOfWork>().InTransientScope();
Bind<IUnitOfWorkFactory>().ToFactory();

Bind<IMyContext>().To<MyContext>().InSingletonScope();

Bind<IAccountTypeRepository>().To<AccountTypeRepository>().InTransientScope();

我会回到 .InSingletonScope();

我看到人们通常这样做的方式是在每个 Repo 的 UoW 属性中都有实现此效果的代码;

private IAccountRepository _accountRepository;
public IAccountRepository Accounts
{
    get 
    { 
         if(_accountRepository = null)
         {
             _accountRepository = new AccountRepository(_context);
         }
         return _accountRepository; 
    }
}

并从 Constructor 中删除注入的存储库,确保存储库的每个实例都使用相同的 _context。

然而在我看来,这打破了 class 的 Dependency Injection。有没有办法做到这一点,每次创建 UoW 都是这样;

public TestUnitOfWork(IUnitOfWorkFactory unitOfWork)
{
    using (var UoW = unitOfWork.Create())
    {
         Work done on UoW... 
    }
}

目前 .InSingletonScope 允许这样做,但这是否使上下文实例始终打开?引入与未正确处理上下文相关的错误?

或者为 Repositories 创建一个 Factory 并给它们一个上下文参数,然后在属性中像这样初始化它更好;

private IAccountRepository _accountRepository;
public IAccountRepository Accounts
{
    get 
    { 
         if(_accountRepository = null)
         {
             _accountRepository = RepositoryFactory.CreateAccountRepository(_context);
         }
         return _accountRepository; 
    }
}

在此先感谢您的帮助!

解决方案是使用 Ninject's Extensions.Factory class 并传入一个 IAccountFactory.Create() 来初始化一个新对象。这然后使用 DI 容器来解决其依赖关系并且不会破坏 DI 方法。