是否有更简洁的方法来在.NET ServiceCollection中注册深度嵌套的特殊依赖项?

问题描述 投票:0回答:1

在 ASP.NET Web 服务中,我有普通的依赖项,例如

services.AddScoped<IEmailService, EmailService>();
services.AddTransient<ICustomerCreationService, CustomerCreationService>();
services.AddTransient<ICustomerValidationService, CustomerValidationService>();
services.AddTransient<ICustomerService, CustomerService>();
services.AddTransient<IBackgroundService, BackgroundService>();
...

但是我们只有一些特殊的情况,只有在特定的情况下我们才需要上述情况的例外,所以我必须执行以下操作。在这个例子中,我想每次在BackgroundService的上下文中需要一个新的IEmailService时使用一个新的实例,而不是使用上面注册的“默认”Scoped实例,所以我需要执行以下操作:

services.AddTransient<BackgroundService>(sp =>
  ActivatorUtilities.CreateInstance<ICustomerService>(sp,
    ActivatorUtilities.CreateInstance<ICustomerValidationService>(sp,
      ActivatorUtilities.CreateInstance<ICustomerCreationService>(sp,
        // this is the only override we actually need (don't use scoped IEmailService)
        ActivatorUtilities.CreateInstance<EmailService>(sp)
      )
    )
  )
);

现在这里 ICustomerService 不需要自己激活;我只是希望它使用上面注册的普通依赖注入。 ICustomerCreationService 和 ICustomerValidationService 也是如此。但我认为我必须使用 ActivatorUtilities 为特殊依赖项的整个树指定参数,对吧?有更优雅的方式吗?我很想在上面说这样的话,但我看不出有什么办法。我错过了吗?

services.AddTransient<IBackgroundService>(sp =>
  ActivatorUtilities.CreateInstanceAtAnyLevel<EmailService>(sp) // I wish...
);
c# dependency-injection activator
1个回答
0
投票

我不确定,但这也许可以帮助你。 https://learn.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services?view=aspnetcore-8.0&tabs=visual-studio

public sealed class BackgroundService: IHostedService, IDisposable
{
public BackgroundService(IServiceScopeFactory serviceScopeFactory)
{
    serviceScope = serviceScopeFactory.CreateScope();
}

public Task StartAsync(CancellationToken cancellationToken)
{
    var services = serviceScope.ServiceProvider;
    var emailService = services.GetRequiredService<IEmailService>();
    
    return Task.CompletedTask;
}

public Task StopAsync(CancellationToken cancellationToken)
{
    return Task.CompletedTask;
}

public void Dispose()
{
    serviceScope.Dispose();
}

}

© www.soinside.com 2019 - 2024. All rights reserved.