如何在 .NET Core 中将 Microsoft.Extensions.DependencyInjection.IServiceScope 注入 class

How to inject an Microsoft.Extensions.DependencyInjection.IServiceScope into a class in .NET Core

我无法将 IServiceScope 注入我的 class。

我的服务实现:

public class AccountService : IAccountService
{
    private readonly IConfiguration _configuration;
    private readonly IServiceScope _services;

    public AccountService(
        IConfiguration configuration,
        IServiceScope services) // <-- I can't inject this
    {
        _configuration = configuration;
        _services = services;
    }

    public async Task CreateAccount(ExternalAccount externalAccount)
    {
        (some code...)
    }
}

在startup.cs中:

services.AddTransient<IAccountService, AccountService>();

问题是项目在上述行后崩溃并出现以下错误:

Some services are not able to be constructed (Error while validating the service descriptor 'ServiceType: IDS.Quickstart.Account.IAccountService Lifetime: Transient ImplementationType: IDS.Quickstart.Account.AccountService': Unable to resolve service for type 'Microsoft.Extensions.DependencyInjection.IServiceScope' while attempting to activate 'IDS.Quickstart.Account.AccountService'.) ---> System.InvalidOperationException: Error while validating the service descriptor 'ServiceType: IDS.Quickstart.Account.IAccountService Lifetime: Transient ImplementationType: IDS.Quickstart.Account.AccountService': Unable to resolve service for type 'Microsoft.Extensions.DependencyInjection.IServiceScope' while attempting to activate 'IDS.Quickstart.Account.AccountService'.

我的代码无法运行的原因是什么?

不是注入 IServiceScope,而是注入 MS.DI,而是注入 IServiceProvider。 MS.DI 将自动注入范围为当前范围的 IServiceProvider 版本。这意味着您的 class 可以调用 IServiceProvider.GetService,这将导致与调用 IServiceScope.ServiceProvider.GetService.

时相同的结果

请小心注入特定于容器的抽象,例如 IServiceProviderIServiceScopeFactoryIServiceScope。如果注入 Composition Root, it leads to the Service Locator anti-pattern 之外的 classes。服务定位器有很多缺点。你的 class、AccountService 的名字让我相信这个 class 存在于你的 Composition Root 之外。

类 位于组合根内部通常仅包含基础结构逻辑(无业务逻辑)。在 Composition Root 中,依赖 DI Container(或其抽象)是很好的,因为这部分已经对特定的 DI Container 有很强的依赖性。

因此,如果可以的话,从 AccountService class 中提取需要解析实例的逻辑,并将其移动到仅由基础架构逻辑组成的 class 中,然后放置它在 Composition Root 中。