如何在ASP.NET Core中同时正确使用Scoped的AddDbContext与Singleton的AddDbContextFactory
解决ASP.NET Core同时注册Scoped DbContext与Singleton DbContextFactory的冲突
当同时注册Scoped生命周期的AddDbContext<MyContext>和Singleton生命周期的AddDbContextFactory<MyContext>时,会触发依赖注入的生命周期冲突错误——默认情况下AddDbContext注册的DbContextOptions<MyContext>是Scoped的,而Singleton的IDbContextFactory<MyContext>无法依赖Scoped服务。
正确的注册方式
直接通过AddDbContext的重载参数指定DbContextOptions的生命周期为Singleton,同时保持DbContext的Scoped特性,再注册Singleton的工厂:
// 注册Scoped的DbContext,同时将DbContextOptions设为Singleton builder.Services.AddDbContext<MyContext>(options => { options.UseNpgsql(connectionString); }, optionsLifetime: ServiceLifetime.Singleton); // 注册Singleton的DbContextFactory builder.Services.AddDbContextFactory<MyContext>(options => { options.UseNpgsql(connectionString); }, lifetime: ServiceLifetime.Singleton);
原理说明
- 将
DbContextOptions<MyContext>的生命周期设为Singleton后,Singleton的工厂可以安全依赖它,避免生命周期冲突。 MyContext本身依然是Scoped,可在请求范围内正常注入使用。- Singleton的
IDbContextFactory<MyContext>可用于后台任务,每次调用CreateDbContext()都会创建独立的DbContext实例,保证线程安全。
内容的提问来源于stack exchange,提问作者Max Bündchen
相关产品推荐
相关产品推荐

