如何在DbContext继承另一个上下文时配置DbContext工厂选项?
解决Blazor中继承DbContext的自定义上下文工厂注册问题
你遇到的核心问题是DbContextOptionsAddDbContextFactory<T>无法自动注入这些依赖。以下是两种可行的解决方案:
方法一:为BlazorAppDbContext构建专属DbContextOptions
步骤1:定义BlazorAppDbContext的构造函数
确保构造函数接受DbContextOptions<BlazorAppDbContext>作为基类参数,同时注入额外服务:
public class BlazorAppDbContext : AppDbContext { private readonly AuthenticationStateProvider _authStateProvider; private readonly IHttpContextAccessor _httpContextAccessor; // 构造函数接受Blazor专属的DbContextOptions和额外依赖 public BlazorAppDbContext(DbContextOptions<BlazorAppDbContext> options, AuthenticationStateProvider authStateProvider, IHttpContextAccessor httpContextAccessor) : base(options) { _authStateProvider = authStateProvider; _httpContextAccessor = httpContextAccessor; // 这里添加Blazor专属代码 } }
步骤2:在Program.cs中注册服务和自定义工厂
首先构建BlazorAppDbContext对应的DbContextOptions,然后注册上下文和自定义DbContextFactory:
// 1. 构建BlazorAppDbContext的DbContextOptions var blazorOptionsBuilder = new DbContextOptionsBuilder<BlazorAppDbContext>(); blazorOptionsBuilder.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")); blazorOptionsBuilder.EnableSensitiveDataLogging(); blazorOptionsBuilder.EnableDetailedErrors(); var blazorDbContextOptions = blazorOptionsBuilder.Options; // 2. 注册BlazorAppDbContext本身 builder.Services.AddTransient(sp => new BlazorAppDbContext(blazorDbContextOptions, sp.GetRequiredService<AuthenticationStateProvider>(), sp.GetRequiredService<IHttpContextAccessor>())); // 3. 注册自定义IDbContextFactory<BlazorAppDbContext>实现 builder.Services.AddTransient<IDbContextFactory<BlazorAppDbContext>>(sp => new BlazorAppDbContextFactory(sp, blazorDbContextOptions));
步骤3:实现自定义DbContextFactory
创建工厂类,负责从服务容器中获取依赖并创建BlazorAppDbContext实例:
public class BlazorAppDbContextFactory : IDbContextFactory<BlazorAppDbContext> { private readonly IServiceProvider _serviceProvider; private readonly DbContextOptions<BlazorAppDbContext> _options; public BlazorAppDbContextFactory(IServiceProvider serviceProvider, DbContextOptions<BlazorAppDbContext> options) { _serviceProvider = serviceProvider; _options = options; } public BlazorAppDbContext CreateDbContext() { return new BlazorAppDbContext(_options, _serviceProvider.GetRequiredService<AuthenticationStateProvider>(), _serviceProvider.GetRequiredService<IHttpContextAccessor>()); } }
方法二:复用AppDbContext的Options并转换类型
如果希望复用AppDbContext的配置,可以将DbContextOptions<AppDbContext>转换为DbContextOptions<BlazorAppDbContext>,通过DbContextOptions的构造函数实现:
步骤1:修改BlazorAppDbContext构造函数
构造函数接受DbContextOptions<AppDbContext>以复用基类配置:
public class BlazorAppDbContext : AppDbContext { private readonly AuthenticationStateProvider _authStateProvider; private readonly IHttpContextAccessor _httpContextAccessor; public BlazorAppDbContext(DbContextOptions<AppDbContext> options, AuthenticationStateProvider authStateProvider, IHttpContextAccessor httpContextAccessor) : base(options) { _authStateProvider = authStateProvider; _httpContextAccessor = httpContextAccessor; } }
步骤2:在Program.cs中注册服务和工厂
// 1. 构建AppDbContext的DbContextOptions var appOptionsBuilder = new DbContextOptionsBuilder<AppDbContext>(); appOptionsBuilder.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")); appOptionsBuilder.EnableSensitiveDataLogging(); appOptionsBuilder.EnableDetailedErrors(); var appDbContextOptions = appOptionsBuilder.Options; // 2. 注册BlazorAppDbContext builder.Services.AddTransient(sp => new BlazorAppDbContext(appDbContextOptions, sp.GetRequiredService<AuthenticationStateProvider>(), sp.GetRequiredService<IHttpContextAccessor>())); // 3. 注册自定义工厂 builder.Services.AddTransient<IDbContextFactory<BlazorAppDbContext>>(sp => new BlazorAppDbContextFactory(sp, appDbContextOptions));
对应调整自定义工厂的构造函数
public class BlazorAppDbContextFactory : IDbContextFactory<BlazorAppDbContext> { private readonly IServiceProvider _serviceProvider; private readonly DbContextOptions<AppDbContext> _options; public BlazorAppDbContextFactory(IServiceProvider serviceProvider, DbContextOptions<AppDbContext> options) { _serviceProvider = serviceProvider; _options = options; } public BlazorAppDbContext CreateDbContext() { return new BlazorAppDbContext(_options, _serviceProvider.GetRequiredService<AuthenticationStateProvider>(), _serviceProvider.GetRequiredService<IHttpContextAccessor>()); } }
内容的提问来源于stack exchange,提问作者Avrohom Yisroel
相关产品推荐
相关产品推荐

