You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

搭配DbContextFactory使用时无法从根提供者解析DbContext的Scoped服务

错误原因

调用CreateDbContext()无参重载时,IDbContextFactory默认会使用初始化阶段绑定的根服务提供者解析DbContext的依赖项。Scoped服务仅能在对应的子作用域内完成解析,根提供者无法直接获取Scoped生命周期的ICurrentUserService,因此抛出对应错误。即使你将DbContext本身注册为Scoped,只要创建阶段的依赖解析走根容器,就会触发该问题,和DbContext本身的注册生命周期无关。

解决方案

方案1(推荐):创建DbContext时传入当前作用域的服务提供者

修改你手写的Scoped DbContext注册逻辑,调用CreateDbContext时将当前作用域的provider作为参数传入,让依赖解析完全走当前请求的子作用域:

services.AddScoped<IMyDbContext>(provider => 
    provider.GetRequiredService<IDbContextFactory<MyDbContext>>().CreateDbContext(provider));
services.AddScoped<MyDbContext>(provider => 
    provider.GetRequiredService<IDbContextFactory<MyDbContext>>().CreateDbContext(provider));

该方案改动最小,不需要调整任何服务的生命周期,也不影响后台任务等无HttpContext场景下对IDbContextFactory的原生使用。

方案2:调整DbContextFactory的生命周期为Scoped

如果你使用.NET 6及以上版本,可以在注册工厂时直接将工厂本身注册为Scoped,和请求生命周期绑定,创建DbContext时会自动走当前作用域解析依赖:

services.AddDbContextFactory<MyDbContext>(options =>
    options.UseSqlServer(config.ConnectionStrings.MSSQLConnection, x =>
    {
        x.MigrationsHistoryTable("...");
        x.MigrationsAssembly("...");
    }),
    ServiceLifetime.Scoped,
    enableScopeValidation: true);

注意该方案下你无法在根作用域(比如后台任务、单例服务)中直接注入使用IDbContextFactory,如果有这类需求不要使用该方案。

注意事项

如果你的CurrentUserService内部依赖IHttpContextAccessor获取当前请求上下文,需要额外注册该服务:

services.AddHttpContextAccessor();

内容的提问来源于stack exchange,提问作者Matthias

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 13:15:02