我应该如何将一个DbContext实例注入IHostedService?
题
我应该如何(使用标准dependency injection)将DbContext
实例注入IHostedService
?
我试过了什么
我目前让我的IHostedService
类在构造函数中获取MainContext
(从DbContext
)实例。
当我运行应用程序时,我得到:
无法从singleton’Microsoft.Extensions.Hosting.IHostedService’中使用作用域服务“Microsoft.EntityFrameworkCore.DbContextOptions”。
所以我尝试通过指定使DbContextOptions
瞬态:
services.AddDbContext(options => options.UseSqlite("Data Source=development.db"), ServiceLifetime.Transient);
在我的Startup
课程中。
但是错误仍然是相同的,即使根据解决的Github问题 ,传递的DbContextOptions
应该具有在AddDbContext
调用中指定的相同生命周期。
我无法使数据库上下文成为单例,否则对它的并发调用将产生并发exception(由于数据库上下文不保证是线程安全的事实)。
在托管服务中使用服务的一种好方法是在需要时创建范围。 这允许使用服务/ db上下文等,以及它们设置的生存期配置。 理论上,不创建范围可能会导致创建单例DbContexts和不正确的上下文重用(EF Core 2.0与DbContext池)。
为此,请注入IServiceScopeFactory
并在需要时使用它来创建范围。 然后解决此范围内所需的所有依赖项。 如果您希望将逻辑移出托管服务并使用托管服务仅触发某些工作(例如,定期触发任务 – 这将定期创建范围,创建任务服务),这也允许您将自定义服务注册为范围依赖项这个范围也得到了一个db上下文注入)。
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(); … } } … }
- C#从另一个表单调用方法
- 在c:\ ProgramFiles \下忽略.Net app.config文件
- 在WPF中,Windows Forms中的Suspend / ResumeLayout()和BackgroundWorker()相当于什么
- 用逗号分隔的类似数组的字符串执行存储过程
- 避免InvalidOperationException的最佳做法:Collection被修改了?
- RichTextBox控件,使非URL超链接?
- 如何将IEnumerable <Task >转换为IObservable
- 通过Windows服务运行时,操作不可用(从HRESULTexception:0x800401E3(MK_E_UNAVAILABLE))?
- Winforms:validationdatagridview中的单元格的问题