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

MassTransit如何禁用publish filter的新DI范围以共享Accessor实例值

解决方案

方案1:使用AsyncLocal实现IAccessor(最推荐)

该方案无需修改MassTransit默认配置,适配性最高,核心是利用AsyncLocal<T>在同一异步调用链的不同DI Scope之间共享数据:

public class Accessor : IAccessor
{
    private static readonly AsyncLocal<Guid> _idStorage = new AsyncLocal<Guid>();
    
    public Guid Id 
    {
        get => _idStorage.Value;
        set => _idStorage.Value = value;
    }
}

IAccessor依然保持Scoped生命周期注册即可,业务代码中设置的Id会被同异步链路下的过滤器正常读取。

方案2:发布时传入当前Scope的ServiceProvider

如果不需要修改Accessor实现,可以在调用Publish方法时传入当前请求的IServiceProvider,MassTransit会直接使用传入的服务提供者解析依赖,不会新建Scope:

public class MyProgram
{
    private readonly IAccessor _accessor;
    private readonly IBus _messageBus;
    private readonly IServiceProvider _serviceProvider;

    public MyProgram(IAccessor accessor, IBus messageBus, IServiceProvider serviceProvider)
    {
        _accessor = accessor;
        _messageBus = messageBus;
        _serviceProvider = serviceProvider;
    }

    public async Task DoThing()
    {
        _accessor.Id = Guid.NewGuid();
        // 传入当前服务提供者复用现有Scope
        await _messageBus.Publish(new Message(), CancellationToken.None, _serviceProvider);
    }
}

方案3:全局关闭发布管道自动创建Scope

如果需要全局生效,可在MassTransit配置中直接关闭发布时新建Scope的逻辑:

builder.Services.AddMassTransit(x =>
{
    // 其他总线注册逻辑
    x.UsingInMemory((context, cfg) =>
    {
        // 全局关闭发布管道自动建Scope逻辑
        cfg.ConfigurePublish(p => p.UseExecute(c => c.CreateNewScope = false));
        cfg.UsePublishFilter(typeof(MyPublishFilter<>), context);
        cfg.ConfigureEndpoints(context);
    });
});

注意:全局关闭后会影响所有发布过滤器的依赖解析,若过滤器中存在非上下文共享的Scoped依赖,可能出现异常,需谨慎使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 22:36:06