You need to enable JavaScript to run this app. Blazor调用IMediator报错:无法从根提供程序解析依赖作用域服务IWegisterDbContext的处理程序
优惠活动
大模型
产品
解决方案
定价
更多

Blazor调用IMediator报错:无法从根提供程序解析依赖作用域服务IWegisterDbContext的处理程序

问题原因

Blazor项目中将CustomerService等业务服务注册为了单例(Singleton),但这些服务依赖的MediatR请求处理器、IWegisterDbContext均为*作用域(Scoped)*服务:

  • 单例服务仅会在应用启动时从根依赖注入容器初始化一次
  • 作用域服务不允许从根容器直接解析,仅能在每请求/每Blazor连接对应的子作用域中解析,因此触发了本次报错。
    REST API项目中所有服务的生命周期是对齐的,所以运行正常。

修复方案

方案1:修改业务服务生命周期(推荐)

将Blazor项目Startup.cs中注册的4个单例服务修改为Scoped生命周期,和依赖的服务生命周期对齐:

// 替换原有的AddSingleton注册
services.AddScoped<SessionService>();
services.AddScoped<WorkHourService>();
services.AddScoped<ItemService>();
services.AddScoped<CustomerService>();

该方案改动最小,也符合EF Core DbContext、MediatR处理器的官方推荐生命周期设计,同时可以避免DbContext多线程复用导致的并发数据异常。

方案2:单例服务内手动创建作用域解析依赖

如果业务逻辑确实需要保留这些服务的单例生命周期,则不要直接在构造函数中注入IMediator或IWegisterDbContext,改为注入IServiceScopeFactory,每次使用依赖时手动创建作用域解析:

public class CustomerService
{
    private readonly IServiceScopeFactory _scopeFactory;

    public CustomerService(IServiceScopeFactory scopeFactory)
    {
        _scopeFactory = scopeFactory;
    }

    public async Task<CustomerListVm> GetCustomersAsync()
    {
        // 手动创建子作用域
        using var scope = _scopeFactory.CreateScope();
        // 从子作用域解析需要的Scoped服务
        var mediator = scope.ServiceProvider.GetRequiredService<IMediator>();
        return await mediator.Send(new GetCustomersListQuery());
    }
}

额外优化建议

AddApplication方法中你已经调用了AddMediatR,它会自动扫描程序集注册所有IRequestHandler实现,手动注册GetCustomersListQueryHandler的代码可以删除,避免重复注册。

内容的提问来源于stack exchange,提问作者SaloméCodes

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.09 01:48:03