Blazor Server中Mediator处理通知时组件属性为null的问题
解决Blazor Server中Mediator处理通知时DbContext为null的问题
核心原因
Blazor Server的组件生命周期与服务范围绑定,而Mediator默认是单例服务。当API发送通知触发组件的Handle方法时,要么组件注入的ApplicationDbContext已超出有效范围被释放,要么Mediator获取组件实例时未正确初始化依赖注入属性,导致NullReferenceException。
可行解决方案
1. 改用手动订阅通知,避免组件直接作为Handler
不要让Blazor组件实现INotificationHandler接口,而是在组件内通过IMediator.Subscribe手动订阅通知,同时用IServiceScopeFactory创建临时服务范围获取有效DbContext:
@implements IDisposable @inject IMediator Mediator @inject IServiceScopeFactory ScopeFactory <!-- 组件UI内容 --> @code { private IDisposable _notificationSubscription; private List<YourEntity> _latestData; protected override void OnInitialized() { // 订阅数据更新通知 _notificationSubscription = Mediator.Subscribe<DataUpdatedNotification>(async notification => { // 创建临时服务范围,获取有效的DbContext using var scope = ScopeFactory.CreateScope(); var dbContext = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>(); // 查询最新数据 _latestData = await dbContext.YourEntities.ToListAsync(); // 通知Blazor更新UI(需在组件线程执行) await InvokeAsync(() => StateHasChanged()); }); } public void Dispose() { // 组件销毁时取消订阅,避免内存泄漏 _notificationSubscription?.Dispose(); } }
2. 确保DbContext的注册方式正确
在Program.cs中确认ApplicationDbContext是按Scoped生命周期注册的:
builder.Services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")), ServiceLifetime.Scoped); // 显式指定Scoped,Blazor Server默认也是该生命周期
3. 检查Mediator源生成配置
确保Mediator源生成正确识别你的通知和处理器:
- 通知类和处理器类需标记为
partial - 在
Program.cs中正确注册Mediator:
builder.Services.AddMediator(options => { // 指定包含通知/处理器的命名空间 options.Namespace = "YourAppNamespace.Mediator"; });
方案优势
- 手动订阅让你完全控制通知处理的生命周期,组件销毁时能及时取消订阅,避免无效实例被调用。
- 通过
IServiceScopeFactory创建的临时范围,每次处理通知都能获取到当前有效的DbContext,不会因为组件范围过期导致null。
内容的提问来源于stack exchange,提问作者Unspoiled9710
相关产品推荐
相关产品推荐

