我应该如何将DbContext实例注入(使用标准依赖注入)IHostedService?
DbContext
IHostedService
目前,我的IHostedService类在构造函数中采用了MainContext(源自DbContext)实例。
MainContext
当我运行该应用程序时,我得到:
无法使用单例“ Microsoft.Extensions.Hosting.IHostedService”中的作用域服务“ Microsoft.EntityFrameworkCore.DbContextOptions”。
因此,我尝试DbContextOptions通过指定以下方式进行过渡:
DbContextOptions
services.AddDbContext<MainContext>(options => options.UseSqlite("Data Source=development.db"), ServiceLifetime.Transient);
在我Startup班上。
Startup
但是,错误仍然保持不变,即使根据此已解决的Github问题,所DbContextOptions传递的应该具有与AddDbContext调用中指定的生存期相同的生存期。
AddDbContext
我不能使数据库上下文成为单例,否则对其的并发调用将产生并发异常(由于不能保证数据库上下文是线程安全的)。
在托管服务中使用服务的一种好方法是在需要时创建作用域。这允许将服务/数据库上下文等与设置它们的生命周期配置一起使用。从理论上说,不创建范围可能导致创建单例DbContext和不正确的上下文重用(带有DbContext池的EF Core 2.0)。
为此,请插入,IServiceScopeFactory并在需要时使用它创建作用域。然后从该作用域中解析您需要的任何依赖项。如果您想将逻辑移出托管服务并仅使用托管服务来触发某些工作(例如,定期触发任务- 这将定期创建范围,在其中创建任务服务),这还允许您将自定义服务注册为范围内的依赖项。这个范围也将注入数据库上下文)。
IServiceScopeFactory
public class MyHostedService : IHostedService { private readonly IServiceScopeFactory scopeFactory; public MyHostedService(IServiceScopeFactory scopeFactory) { this.scopeFactory = scopeFactory; } public void DoWork() { using (var scope = scopeFactory.CreateScope()) { var dbContext = scope.ServiceProvider.GetRequiredService<MyDbContext>(); … } } … }