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

ASP.NET Core中如何注入多个同连接字符串不同队列的ServiceBusClient

实现多个不同队列ServiceBus实例注入的方案

注意:连接字符串相同的场景下,无需创建多个ServiceBusClient实例,该类本身线程安全,复用单实例即可减少不必要的连接开销。

方案1:使用键控服务(适用于ASP.NET Core 8+)

键控服务支持通过不同标识区分同类型的不同实例,是最简便的实现方式:

  1. 先配置服务总线参数,在appsettings.json中添加配置:
"ServiceBusSettings": {
  "ConnectionString": "你的Azure Service Bus连接字符串",
  "Queues": {
    "UserEventQueue": "user-event-queue",
    "CarReservationQueue": "car-reservation-queue"
  }
}
  1. 创建对应的配置绑定类:
public class ServiceBusSettings
{
    public string ConnectionString { get; set; }
    public Dictionary<string, string> Queues { get; set; }
}
  1. 注册服务实例,用队列名称作为区分不同实例的键:
// 绑定配置
builder.Services.Configure<ServiceBusSettings>(builder.Configuration.GetSection("ServiceBusSettings"));

// 注册共享的ServiceBusClient单例
builder.Services.TryAddSingleton<ServiceBusClient>(sp =>
{
    var settings = sp.GetRequiredService<IOptions<ServiceBusSettings>>().Value;
    return new ServiceBusClient(settings.ConnectionString, new ServiceBusClientOptions
    {
        TransportType = ServiceBusTransportType.AmqpWebSockets
    });
});

// 注册不同队列的Receiver
builder.Services.AddKeyedSingleton<ServiceBusReceiver>("UserEventQueue", (sp, key) =>
{
    var client = sp.GetRequiredService<ServiceBusClient>();
    var settings = sp.GetRequiredService<IOptions<ServiceBusSettings>>().Value;
    return client.CreateReceiver(settings.Queues[key.ToString()], new ServiceBusReceiverOptions
    {
        ReceiveMode = ServiceBusReceiveMode.PeekLock
    });
});
builder.Services.AddKeyedSingleton<ServiceBusReceiver>("CarReservationQueue", (sp, key) =>
{
    var client = sp.GetRequiredService<ServiceBusClient>();
    var settings = sp.GetRequiredService<IOptions<ServiceBusSettings>>().Value;
    return client.CreateReceiver(settings.Queues[key.ToString()], new ServiceBusReceiverOptions
    {
        ReceiveMode = ServiceBusReceiveMode.PeekLock
    });
});

// 注册不同队列的Sender
builder.Services.AddKeyedSingleton<ServiceBusSender>("CarReservationQueue", (sp, key) =>
{
    var client = sp.GetRequiredService<ServiceBusClient>();
    var settings = sp.GetRequiredService<IOptions<ServiceBusSettings>>().Value;
    return client.CreateSender(settings.Queues[key.ToString()]);
});
  1. 使用时通过[FromKeyedServices]特性指定要注入的实例:
private readonly ServiceBusSender _serviceBusSender;

public CarReservationMessagingService([FromKeyedServices("CarReservationQueue")] ServiceBusSender serviceBusSender)
{
    _serviceBusSender = serviceBusSender ?? throw new ArgumentNullException(nameof(serviceBusSender));
}

方案2:自定义工厂类(适用于所有ASP.NET Core版本)

如果使用低于.NET 8的版本,没有键控服务能力,可以通过自定义工厂类实现实例区分:

  1. 编写工厂接口和实现类:
public interface IServiceBusFactory
{
    ServiceBusReceiver GetReceiver(string queueKey);
    ServiceBusSender GetSender(string queueKey);
}

public class ServiceBusFactory : IServiceBusFactory
{
    private readonly ServiceBusClient _client;
    private readonly ServiceBusSettings _settings;
    private readonly ConcurrentDictionary<string, ServiceBusReceiver> _receiverCache = new();
    private readonly ConcurrentDictionary<string, ServiceBusSender> _senderCache = new();

    public ServiceBusFactory(ServiceBusClient client, IOptions<ServiceBusSettings> settings)
    {
        _client = client;
        _settings = settings.Value;
    }

    public ServiceBusReceiver GetReceiver(string queueKey)
    {
        return _receiverCache.GetOrAdd(queueKey, key => 
            _client.CreateReceiver(_settings.Queues[key], new ServiceBusReceiverOptions
            {
                ReceiveMode = ServiceBusReceiveMode.PeekLock
            })
        );
    }

    public ServiceBusSender GetSender(string queueKey)
    {
        return _senderCache.GetOrAdd(queueKey, key => 
            _client.CreateSender(_settings.Queues[key])
        );
    }
}
  1. 注册服务:
builder.Services.Configure<ServiceBusSettings>(builder.Configuration.GetSection("ServiceBusSettings"));
builder.Services.TryAddSingleton<ServiceBusClient>(sp =>
{
    var settings = sp.GetRequiredService<IOptions<ServiceBusSettings>>().Value;
    return new ServiceBusClient(settings.ConnectionString, new ServiceBusClientOptions
    {
        TransportType = ServiceBusTransportType.AmqpWebSockets
    });
});
builder.Services.TryAddSingleton<IServiceBusFactory, ServiceBusFactory>();
  1. 使用时注入工厂获取对应实例:
private readonly ServiceBusSender _serviceBusSender;

public CarReservationMessagingService(IServiceBusFactory serviceBusFactory)
{
    _serviceBusSender = serviceBusFactory.GetSender("CarReservationQueue") ?? throw new ArgumentNullException(nameof(_serviceBusSender));
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.17 00:24:04