【问题标题】:How to inject dependencies from IHostedService before creating scope如何在创建范围之前从 IHostedService 注入依赖项
【发布时间】:2022-08-11 22:36:28
【问题描述】:
我有一个带有后台作业的多租户系统。租户详细信息存储在数据库中,并且基于租户在服务总线中添加请求,我想根据租户解决依赖关系。
为此,我必须在创建范围之前将依赖项添加到服务集合。尝试注入 IServiceCollection 时,它给了我错误。
我正在寻找从 HostedService 注入依赖项的最佳方法
public async Task MessageHandler(object sender, Message message)
{
// Inject dependencies
services.AddScoped<IMyService,Myservice>(); // No way to get services here
using (var scope = serviceProvider.CreateScope())
{
var ... = scope.ServiceProvider.GetService<...>();
//...
}
}
标签:
c#
.net-core
dependency-injection
backgroundworker
azure-servicebus-queues
【解决方案1】:
不久前我也有类似的需求。我创建了自己的服务总线处理程序。
您可以尝试类似下面的方法,在其中将服务(这里作为示例,我使用 IMessageService)注入到 ServiceeBusHandler,该 ServiceeBusHandler 本身具有注入的 dbcontext。
然后,无论您在何处实现 IServiceBusHandler,您都可以指定要为哪个租户(及其队列)建立连接。
public class ServiceBusHandler : IServiceBusHandler
{
private readonly ServiceBusSender _serviceBusSender;
private readonly IMessageService _messageService;
public ServiceBusHandler(
ServiceBusSender serviceBusSender,
IMessageService messageService)
{
_serviceBusSender = serviceBusSender;
_messageService = messageService;
}
public async Task PublishMessageAsync<T>(T message)
{
var jsonString = JsonConvert.SerializeObject(message);
var serviceBusMessage = new ServiceBusMessage(jsonString);
await _serviceBusSender.SendMessageAsync(serviceBusMessage);
}
internal static IServiceBusHandler Create(ServiceBusSender sender)
{
return new ServiceBusHandler(sender);
}
}
public class ServiceBusHandlerFactory : IServiceBusHandlerFactory
{
private readonly IAzureClientFactory<ServiceBusClient> _serviceBusClientFactory;
public ServiceBusHandlerFactory(
IAzureClientFactory<ServiceBusClient> serviceBusClientFactory)
{
_serviceBusClientFactory = serviceBusClientFactory;
}
public IServiceBusHandler GetClient(string tenantId)
{
var tenantDetails _messageService.GetTenantDetails(tenantId); // Call to your DB to get details about the Tenant
var client = GetServiceBusClient(tenantDetails.QueueName);
var sender = client.CreateSender(tenantDetails.QueueName);
return ServiceBusHandler.Create(sender);
}
protected virtual ServiceBusClient GetServiceBusClient(string queueName)
{
var client = _serviceBusClientFactory.CreateClient(queueName);
return client;
}
}