如何在 C# 中对工作单元和存储库使用依赖注入? (不是基于网络的应用程序)
How do I use Dependency Injection with Unit of Work and Repositories in C#? (Not a web based App)
我看到很多关于这个主题的问题和答案,但是绝大多数都在处理 ASP.Net
或其他基于 Web 的应用程序以及称为 .InRequestScope
的东西。我还没有在 Ninject
和 Windows 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 方法。
我看到很多关于这个主题的问题和答案,但是绝大多数都在处理 ASP.Net
或其他基于 Web 的应用程序以及称为 .InRequestScope
的东西。我还没有在 Ninject
和 Windows 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 方法。