【问题标题】: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<...>();
           //...
     }
}
  • 使用默认 DI 容器,您无法在构建后注入服务。
  • 是否有任何其他 DI 可以提供这种灵活性?

标签: 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;
    }
}

【讨论】:

    猜你喜欢
    • 2021-12-07
    • 2017-03-20
    • 2017-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-16
    • 2017-04-25
    • 2014-12-02
    相关资源
    最近更新 更多