Blazor Server自定义DbContext集成Identity及DbContextFactory报错解决
在Blazor Server+EF Core 7+Identity中使用自定义DbContext并解决IDbContextFactory注入异常
问题场景
需要替换Blazor Server默认的ApplicationDbContext为自定义OpmContext,同时要在Razor页面或自定义服务中注入IDbContextFactory<OpmContext>使用。
默认Program.cs代码:
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection") ?? throw new InvalidOperationException("Connection string 'DefaultConnection' not found."); builder.Services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(connectionString));
修改后的代码:
Program.cs
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection") ?? throw new InvalidOperationException("Connection string 'DefaultConnection' not found."); void BuildOptions(DbContextOptionsBuilder options) => options.UseSqlServer(connectionString).EnableSensitiveDataLogging(); // todo: not for production builder.Services.AddDbContext<OpmContext>(BuildOptions); builder.Services.AddDbContextFactory<OpmContext>(BuildOptions); builder.Services.AddDatabaseDeveloperPageExceptionFilter(); builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true) .AddEntityFrameworkStores<OpmContext>();
自定义DbContext
public class OpmContext : IdentityDbContext { public OpmContext(DbContextOptions<OpmContext> options) : base(options) { } }
异常信息
System.AggregateException: 'Some services are not able to be constructed (Error while validating the service descriptor 'ServiceType: Microsoft.EntityFrameworkCore.IDbContextFactory`1[Foo.Bar.Data.OpmContext] Lifetime: Singleton
解决方案
问题根源是同时注册AddDbContext和AddDbContextFactory时,DbContext的生命周期与Identity依赖的Scoped实例冲突,且重复配置导致服务注册异常。调整注册逻辑如下:
修改Program.cs代码
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection") ?? throw new InvalidOperationException("Connection string 'DefaultConnection' not found."); // 统一配置DbContextOptions builder.Services.AddDbContextOptions<OpmContext>(options => { options.UseSqlServer(connectionString) .EnableSensitiveDataLogging(); // 生产环境请移除 }); // 注册DbContextFactory(默认生命周期为Singleton,符合要求) builder.Services.AddDbContextFactory<OpmContext>(); // 注册Scoped生命周期的OpmContext供Identity使用,通过Factory创建实例 builder.Services.AddScoped(sp => sp.GetRequiredService<IDbContextFactory<OpmContext>>().CreateDbContext()); builder.Services.AddDatabaseDeveloperPageExceptionFilter(); builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true) .AddEntityFrameworkStores<OpmContext>();
说明
- 先通过
AddDbContextOptions统一配置DbContext的选项,避免重复配置导致的冲突 - 只注册
AddDbContextFactory来提供工厂实例,满足注入IDbContextFactory<OpmContext>的需求 - 手动注册Scoped生命周期的
OpmContext,通过工厂创建实例,确保Identity能获取到符合其生命周期要求的DbContext实例 - 自定义DbContext继承
IdentityDbContext的代码无需修改,已满足Identity的基础要求
内容的提问来源于stack exchange,提问作者juFo
相关产品推荐
相关产品推荐

