如何注册 ServiceBusClient 以进行依赖注入?
Posted
技术标签:
【中文标题】如何注册 ServiceBusClient 以进行依赖注入?【英文标题】:How to register ServiceBusClient for dependency injection? 【发布时间】:2021-10-11 18:38:02 【问题描述】:我正在尝试使用 ServiceBusClientBuilderExtensions
从新的 Azure.Messaging.ServiceBus 包中注册 ServiceBusClient
以进行依赖注入,如本 article 中所建议的那样,但我找不到任何文档或任何有关如何执行此操作的在线帮助。
我正在尝试添加如下
public override void Configure(IFunctionsHostBuilder builder)
ServiceBusClientBuilderExtensions.AddServiceBusClient(builder, Typsy.Domain.Configuration.Settings.Instance().Connections.ServiceBusPrimary);
但我得到了错误
“Microsoft.Azure.Functions.Extensions.DependencyInjection.IFunctionsHostBuilder”类型必须可转换为“Azure.Core.Extensions.IAzureClientFactoryBuilder”才能在通用方法“IAzureClientBuilder
Microsoft.Extensions.Azure.ServiceBusClientBuilderExtensions.AddServiceBusClient(this TBuilder, string)'
如果有人能帮上忙,那就太好了!
【问题讨论】:
【参考方案1】:ServiceBusClientBuilderExtensions.AddServiceBusClient
是IAzureClientFactoryBuilder
的扩展方法:
public static IAzureClientBuilder<ServiceBusClient, ServiceBusClientOptions> AddServiceBusClient<TBuilder>(this TBuilder builder, string connectionString)
where TBuilder : IAzureClientFactoryBuilder
要获得IAzureClientFactoryBuilder
的实例,您需要为给定的IServiceCollection
调用AzureClientServiceCollectionExtensions.AddAzureClients(IServiceCollection, Action<AzureClientFactoryBuilder>)
,它提供了一个提供IAzureClientFactoryBuilder
实例的委托。 (此方法在Microsoft.Extensions.Azure
NuGet 包中)
要调用该方法,您可以使用IFunctionsHostBuilder
提供的IServiceCollection
。有了所有这些,您所拥有的应该如下所示:
public override void Configure(IFunctionsHostBuilder builder)
builder.Services.AddAzureClients(clientsBuilder =>
clientsBuilder.AddServiceBusClient(Typsy.Domain.Configuration.Settings.Instance().Connections.ServiceBusPrimary)
// (Optional) Provide name for instance to retrieve by with DI
.WithName("Client1Name")
// (Optional) Override ServiceBusClientOptions (e.g. change retry settings)
.ConfigureOptions(options =>
options.RetryOptions.Delay = TimeSpan.FromMilliseconds(50);
options.RetryOptions.MaxDelay = TimeSpan.FromSeconds(5);
options.RetryOptions.MaxRetries = 3;
);
);
要检索命名实例,您可以使用IAzureClientFactory<ServiceBusClient>
,而不是使用ServiceBusClient
作为注入类型。 无论您是否使用命名实例,ServiceBusClient
都是单例。
public Constructor(IAzureClientFactory<ServiceBusClient> serviceBusClientFactory)
// Wherever you need the ServiceBusClient
ServiceBusClient singletonClient1 = serviceBusClientFactory.CreateClient("Client1Name")
【讨论】:
这如何与多个命名空间或连接字符串一起工作? @devNull 你也知道注册ServiceBusClient作为依赖的时候,是注册为单例吗?如果没有,您对我如何将其注册为单身人士有任何想法吗? 你知道在注册 ServiceBusClient 作为依赖项时如何传入 ServiceBusClientOptions 吗? 要从 ConfigureService 方法访问设置,您可以使用 var connectionString = Environment.GetEnvironmentVariable("ConnectionStrings:ServiceConnectionStrings"); - 参见微软关于环境变量的文章:docs.microsoft.com/en-us/azure/azure-functions/… @codea 使用上下文也可以是一个选项docs.microsoft.com/en-us/azure/azure-functions/…【参考方案2】:对于那些只需要单个服务总线客户端的人来说,一个简单的单例就足够了
(使用 .Net 6 Azure Functions v4 测试):
using Azure.Messaging.ServiceBus;
using Microsoft.Azure.Functions.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;
using System;
[assembly: FunctionsStartup(typeof(YourProjName.Startup))]
namespace YourProjName
public class Startup : FunctionsStartup
public override void Configure(IFunctionsHostBuilder builder)
var serviceBusConnectionString = Environment.GetEnvironmentVariable("ServiceBusConnectionString");
if (string.IsNullOrEmpty(serviceBusConnectionString))
throw new InvalidOperationException(
"Please specify a valid ServiceBusConnectionString in the Azure Functions Settings or your local.settings.json file.");
//using AMQP as transport
builder.Services.AddSingleton((s) =>
return new ServiceBusClient(serviceBusConnectionString, new ServiceBusClientOptions() TransportType = ServiceBusTransportType.AmqpWebSockets );
);
然后你可以在 Azure Function 构造函数中使用它:
public Function1(ServiceBusClient client)
_client = client;
【讨论】:
【参考方案3】:我想知道完全相同的事情,虽然我喜欢有一个专门的 azure 扩展,但我确实找到了另一种我更喜欢的方式,它看起来不那么复杂,希望这可以帮助其他人。
代码使用.AddSingleton Method 提供的函数委托。此函数委托将在构建的最后被调用,您可以在其中使用服务提供者并检索您的选项(如果我错了,请纠正我,因为文档既密集又稀疏:))。
以下是关键部分:
serviceCollection.AddSingleton((serviceProvider) =>
ServiceBusOptions options = serviceProvider.GetService<IOptions<ServiceBusOptions>>().Value;
return new ServiceBusClient(options.ConnectionString);
);
**完整代码 - 说得更多:) **
使用 Azure.Messaging.ServiceBus; 使用 Microsoft.Extensions.Configuration; 使用 Microsoft.Extensions.DependencyInjection; 使用 Microsoft.Extensions.Hosting; 使用 Microsoft.Extensions.Options;
命名空间 ConsoleJson.Example 类启动 私有静态 IHost DIHost;
static void Main(string[] args)
IHostBuilder hostbuilder = Host.CreateDefaultBuilder(args)
.ConfigureAppConfiguration(GetAppConfigurationDefinition);
//Create Host (/build configuration)
ConfigureSettings(hostbuilder);
ConfigureServices(hostbuilder);
DIHost = hostbuilder.Build();
// Application code should start here.
DIHost.Run();
static void GetAppConfigurationDefinition(HostBuilderContext ctx, IConfigurationBuilder config)
config.SetBasePath(Environment.CurrentDirectory)
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) // for simplicity appsettings.production.json / appsettings.development.json are not there. This is where settings would go.
.Build();
public static void ConfigureServices(IHostBuilder hostbuilder)
hostbuilder.ConfigureServices((hostContext, serviceCollection) =>
serviceCollection.AddSingleton<ServiceBusClient>((serviceProvider) =>
// options from appSettings.json
// leverages IOptions Pattern to get an options object from the DIHost Service provider
var myServiceBusOptions = serviceProvider.GetService<IOptions<ServiceBusOptions>>().Value;
var sbClientOptions=new ServiceBusClientOptions()
TransportType=ServiceBusTransportType.AmqpTcp,
RetryOptions=new ServiceBusRetryOptions() Mode = ServiceBusRetryMode.Exponential
// ...
;
// returns the ServiceBusClient Object configured per options we wanted
return new ServiceBusClient(myServiceBusOptions.ConnectionString, sbClientOptions);
);
);
public static void ConfigureSettings(IHostBuilder hostbuilder)
hostbuilder.ConfigureServices((hostBuilderContext, serviceCollection) =>
IConfiguration configurationRoot = hostBuilderContext.Configuration;
serviceCollection.Configure<ServiceBusOptions>(configurationRoot.GetSection("ServiceBusOptions"));
);
public class ServiceBusOptions
public string ConnectionString get; set;
AppSettings.Json
"ServiceBusOptions":
"ConnectionString": ""
【讨论】:
以上是关于如何注册 ServiceBusClient 以进行依赖注入?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 ASP.NET MVC 6 中注册 ILogger 以进行注入
如何注册 GCM 和 APNS,获取 DeviceId 并将我的 API 发送给它以进行数据库存储?
如何以编程方式获取 Firebase 中的注册用户列表 [重复]