[英]Common DB Access repository for ASP.NET Core Web App and Worker Service - managing context
I have an app with a common database requirement for an ASP.Net Core web app and an ASP.Net Core Worker service background task.我有一个对 ASP.Net Core web 应用程序和一个 ASP.Net Core Worker 服务后台任务具有通用数据库要求的应用程序。 I have a standard Repository pattern based approach with a class for each entity (standard CRUD operations).我有一个基于标准存储库模式的方法,每个实体都有一个 class(标准 CRUD 操作)。
My question concerns the best approach to manage the Db context injection into the Repository class for both apps.我的问题涉及为两个应用程序管理 Db 上下文注入到存储库 class 的最佳方法。 This is easy for the ASP.Net Core web app: Constructor based DI each time a Db context is required.这对于 ASP.Net Core web 应用程序来说很容易:每次需要 Db 上下文时,基于构造函数的 DI。 However, the worker service requires obtaining a fresh Db context for every ExecuteAsync iteration, and passing it to each repository class by some means.但是,worker 服务需要为每个 ExecuteAsync 迭代获取一个新的 Db 上下文,并通过某种方式将其传递给每个存储库 class。 This works, but is a bit messy:这可行,但有点混乱:
code
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
using var scope = _serviceScopeFactory.CreateScope();
var dbContext = scope.ServiceProvider.GetRequiredService<MyDbContext>();
...
}
}
code
I'm interested in a single Db data access point design pattern that will manage both apps while also getting thread-safe Db contexts when required.我对单个 Db 数据访问点设计模式感兴趣,该模式将管理两个应用程序,同时在需要时获得线程安全的 Db 上下文。
Any help greatly appreciated非常感谢任何帮助
I have come up with a workable Repository Pattern per entity implementation that works for both the ASP.NET core web app and Worker Service.我已经为每个实体实现提出了一个可行的存储库模式,它适用于 ASP.NET 核心 web 应用程序和 Worker Service。 Here is the code to do this:这是执行此操作的代码:
public interface IApplianceRepository
{
Task UpdateApplianceDetailsAsync(Appliance appliance);
Task CreateApplianceAsync(Appliance appliance);
…
}
public class SqlApplianceRepository : IApplianceRepository
{
protected IDbContext _db;
public SqlApplianceRepository() {}
public SqlApplianceRepository(IDbContext db)
{
_db = db;
}
public virtual async Task CreateApplianceDetailsAsync(Appliance appliance)
{
…
}
public virtual async Task UpdateApplianceDetailsAsync(Appliance appliance)
{
…
}
…
}
public class SqlApplianceRepositoryWorkerService : SqlApplianceRepository
{
public override async Task CreateApplianceAsync(Appliance appliance)
{
_db = DbContextFactory.GetCurrentDbContext();
await base.CreateApplianceAsync(appliance);
}
public override async Task UpdateApplianceDetailsAsync(Appliance appliance)
{
_db = DbContextFactory.GetCurrentDbContext();
await base.UpdateApplianceDetailsAsync(appliance);
}
…
}
Both SqlApplianceRepository and SqlApplianceRepositoryWorkerService are configured as transient services and injected where required in their respective apps. SqlApplianceRepository 和 SqlApplianceRepositoryWorkerService 都配置为临时服务,并在各自应用程序中需要的地方注入。 DbContextFactory.GetCurrentDbContext() gets a Db context created for every Worker Service call to ExecuteAsync(). DbContextFactory.GetCurrentDbContext() 获取为每个对 ExecuteAsync() 的 Worker Service 调用创建的 Db 上下文。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.