如何在存储库中注入 IServiceProvider 来实现工作单元模式?
How to implement unit of work pattern with IServiceProvider injected in repositories?
我必须在我的项目中实现工作单元模式,但我找不到使用内存数据库执行此操作的正确方法。我有两个存储库:
public class RepositoryA : IRepositoryA
{
private readonly IServiceScope _scope;
private readonly ApiContext _apiContext;
public RepositoryA(IServiceProvider services)
{
_scope = services.CreateScope();
_apiContext = _scope.ServiceProvider.GetRequiredService<ApiContext>();
}
//some methods
}
public class RepositoryB : IRepositoryB
{
private readonly IServiceScope _scope;
private readonly ApiContext _apiContext;
public RepositoryB(IServiceProvider services)
{
_scope = services.CreateScope();
_apiContext = _scope.ServiceProvider.GetRequiredService<ApiContext>();
}
//some methods
}
我发现了一些在其他项目中工作的工作单元模式的好例子。
public interface IUnitOfWork
{
public IRepositoryA IRepositoryA { get; }
public IRepositoryB IRepositoryB { get; }
void SaveChanges();
}
public class UnitOfWork : IUnitOfWork
{
private ApiContext _apiContext;
private IRepositoryA _repositoryA ;
private IRepositoryB _repositoryB ;
public UnitOfWork(ApiContext apiContext)
{
_apiContext = apiContext;
}
public IRepositoryA RepositoryA
{
get
{
if(_repositoryA == null)
{
_repositoryA = new RepositoryA(_apiContext);
}
return _repositoryA ;
}
}
public IRepositoryB RepositoryB
{
get
{
if(_repositoryB == null)
{
_repositoryB = new RepositoryB(_apiContext);
}
return _repositoryB;
}
}
public void SaveChanges()
{
_apiContext.SaveChangesAsync();
}
}
在我的 Startup.cs 我的 ConfigureServices 方法中有这个:
services.AddSingleton<IUnitOfWork, UnitOfWork>();
services.AddSingleton<IRepositoryA, RepositoryA>();
services.AddSingleton<IRepositoryB, RepositoryB>();
services.AddDbContext<ApiContext>(options => options.UseInMemoryDatabase("Database"));
在此示例中,工作单元试图将 apiContext 传递给存储库构造函数。我不能这样做,因为两个存储库都不期望构造函数中的 apiContext,而是 IServiceProvider。当我尝试像这样创建我的存储库时:
public RepositoryA(ApiContext apiContext)
{
_apiContext = apiContext;
}
我收到一个错误:
InvalidOperationException: 无法从单例 Project.Repositories.Interface.IRepositoryA.
使用作用域服务 Project.Data.ApiContext'
这个错误是因为内存数据库。所以我需要在存储库的构造函数中注入 IServiceProvider 并创建范围,这是在没有工作单元的情况下工作的。但是现在我需要工作单元,但我不知道如何实现它。有什么方法可以以不同的方式实现工作单元,或者更改我的存储库?
如错误所示,您不应将范围内的生命周期依赖项注入单例。 DbContexts 通常注册为作用域。
如果存储库依赖于上下文,那么它们也应该被限定范围。
例如
services.AddScope<IUnitOfWork, UnitOfWork>();
services.AddScope<IRepositoryA, RepositoryA>();
services.AddScope<IRepositoryB, RepositoryB>();
services.AddDbContext<ApiContext>(options => options.UseInMemoryDatabase("Database"));
我必须在我的项目中实现工作单元模式,但我找不到使用内存数据库执行此操作的正确方法。我有两个存储库:
public class RepositoryA : IRepositoryA
{
private readonly IServiceScope _scope;
private readonly ApiContext _apiContext;
public RepositoryA(IServiceProvider services)
{
_scope = services.CreateScope();
_apiContext = _scope.ServiceProvider.GetRequiredService<ApiContext>();
}
//some methods
}
public class RepositoryB : IRepositoryB
{
private readonly IServiceScope _scope;
private readonly ApiContext _apiContext;
public RepositoryB(IServiceProvider services)
{
_scope = services.CreateScope();
_apiContext = _scope.ServiceProvider.GetRequiredService<ApiContext>();
}
//some methods
}
我发现了一些在其他项目中工作的工作单元模式的好例子。
public interface IUnitOfWork
{
public IRepositoryA IRepositoryA { get; }
public IRepositoryB IRepositoryB { get; }
void SaveChanges();
}
public class UnitOfWork : IUnitOfWork
{
private ApiContext _apiContext;
private IRepositoryA _repositoryA ;
private IRepositoryB _repositoryB ;
public UnitOfWork(ApiContext apiContext)
{
_apiContext = apiContext;
}
public IRepositoryA RepositoryA
{
get
{
if(_repositoryA == null)
{
_repositoryA = new RepositoryA(_apiContext);
}
return _repositoryA ;
}
}
public IRepositoryB RepositoryB
{
get
{
if(_repositoryB == null)
{
_repositoryB = new RepositoryB(_apiContext);
}
return _repositoryB;
}
}
public void SaveChanges()
{
_apiContext.SaveChangesAsync();
}
}
在我的 Startup.cs 我的 ConfigureServices 方法中有这个:
services.AddSingleton<IUnitOfWork, UnitOfWork>();
services.AddSingleton<IRepositoryA, RepositoryA>();
services.AddSingleton<IRepositoryB, RepositoryB>();
services.AddDbContext<ApiContext>(options => options.UseInMemoryDatabase("Database"));
在此示例中,工作单元试图将 apiContext 传递给存储库构造函数。我不能这样做,因为两个存储库都不期望构造函数中的 apiContext,而是 IServiceProvider。当我尝试像这样创建我的存储库时:
public RepositoryA(ApiContext apiContext)
{
_apiContext = apiContext;
}
我收到一个错误:
InvalidOperationException: 无法从单例 Project.Repositories.Interface.IRepositoryA.
使用作用域服务 Project.Data.ApiContext'这个错误是因为内存数据库。所以我需要在存储库的构造函数中注入 IServiceProvider 并创建范围,这是在没有工作单元的情况下工作的。但是现在我需要工作单元,但我不知道如何实现它。有什么方法可以以不同的方式实现工作单元,或者更改我的存储库?
如错误所示,您不应将范围内的生命周期依赖项注入单例。 DbContexts 通常注册为作用域。
如果存储库依赖于上下文,那么它们也应该被限定范围。
例如
services.AddScope<IUnitOfWork, UnitOfWork>();
services.AddScope<IRepositoryA, RepositoryA>();
services.AddScope<IRepositoryB, RepositoryB>();
services.AddDbContext<ApiContext>(options => options.UseInMemoryDatabase("Database"));