我尝试在我的基础设施层实现一个存储库。我不使用dbContext作为工作单元,而是使用每个repo方法完成自己的工作。我将在上面的层中实现事务,以将回购方法结合在一起。
在我以前的生活中(不是在。net Core中),我的repo方法通常如下:
class MyRepo:IMyRepo
{
public void Save(MyObject p)
{
using(var ctx = new MyDbContext())
{
ctx.MyTable.Add( ...);
ctx.SaveChanges();
}
在Core和DI的奇妙世界中,我尝试像下面这样实现方法:
方法1 -添加DbContextOptions到DI
class MyRepo : IMyRepo
{
private readonly DbContextOptions<MyDbContext> Options;
public MyRepo(DbContextOptions<MyDbContext> options)
{
Options = options;
}
public void Save(MyObject p)
{
using var ctx = new MyDbContext(this.Options);
...
方法2 -将DbContextFactory添加到DI
class MyRepo:IMyRepo
{
private readonly DbContextFactory<MyDbContext> Factory;
public MyRepo(DbContextFactory<MyDbContext> factory)
{
Factory = factory;
}
public void Save(MyObject p)
{
using var ctx = Factory.CreateDbContext();
...
方法3 -将DbContextPool添加到DI
class MyRepo:IMyRepo
{
private readonly DbContextPool<MyDbContext> Pool;
public MyRepo(DbContextPool<MyDbContext> pool)
{
Pool = pool;
}
public void Save(MyObject p)
{
using var ctx = Pool.GetCtxInstance(); ? ???
...
我想用两种方式对我的存储库进行单元测试:
- 在本地。mdf文件上,连接到它并执行真正的sql操作并检查它们的结果
- 我计划使用假存储库测试域服务。我读到有一种方法可以使用"内存表"来伪造存储库,在这种情况下,我认为我必须在测试期间以某种方式替换我的DbContext实例
我的问题:
- 在第三种方式如何获得一个新的上下文实例(当池被使用?)?还是像
ctx = new MyDbContext()
那么简单? - 这是一个现实生活中的例子,假的MyDbContext本身,不只是改变它的"选项"?如何伪装?为什么?
- 在这种情况下,我认为工厂是最好的,因为我可以实现其他方法来创建dbcontext用于稍后的测试。是吗?
- 那么,哪一种最好的方法能够对存储库本身和使用伪造存储库的域服务执行单元测试?
您对实现存储库有什么建议?提前感谢!
您对实现存储库有什么建议?
-
没有。DbContext是一个非常好的存储库。就用它吧
-
如果你这样做了,在额外的repo中注入一个DbContext子类型的实例。然后,DI可以处理DBContext的生命周期,并且您将能够按照您的设想管理事务,因为一个范围内的所有repos将共享DBContext实例。