如何使用依赖注入在 C# 工作进程中使用作用域服务

How to use scoped services within a in C# worker process using Dependency Injection

我正在创建 C# 工作进程并且在定义依赖项时遇到问题。

我有一个名为 VMValidationManager 的 class,它实现了接口 IVMValidationManager

public interface IVMValidationManager
{
    void RunVMValidationScripts();
}

public class VMValidationManager : IVMValidationManager
{
    List<string> failedScripts = new List<string>();
}

还有 Worker class 我想在其中注入 IVMValidationManager

public class Worker : BackgroundService
{
    private readonly IVMValidationManager _vmValidationManager;

public Worker(IVMValidationManager vmValidationManager)
{
    _vmValidationManager = vmValidationManager;
}


protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
    _vmValidationManager.RunVMValidationScripts();
}
}

在 Program.cs 我有这个代码

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
}

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
    .UseWindowsService()
        .ConfigureServices((hostContext, services) =>
        {
            services.AddScoped<IVMValidationManager, VMValidationManager>();
            services.AddHostedService<Worker>();
        });
}

当 运行 我收到错误消息。堆栈跟踪

Cannot consume scoped service 'VMAgent.Services.IVMValidationManager' from singleton 'Microsoft.Extensions.Hosting.IHostedService'.


   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteValidator.VisitScopeCache(ServiceCallSite scopedCallSite, CallSiteValidatorState state)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteValidator.VisitConstructor(ConstructorCallSite constructorCallSite, CallSiteValidatorState state)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteValidator.VisitRootCache(ServiceCallSite singletonCallSite, CallSiteValidatorState state)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteValidator.ValidateCallSite(ServiceCallSite callSite)
   at Microsoft.Extensions.DependencyInjection.ServiceProvider.Microsoft.Extensions.DependencyInjection.ServiceLookup.IServiceProviderEngineCallback.OnCreate(ServiceCallSite callSite)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.ValidateService(ServiceDescriptor descriptor)

我做错了什么?

您正在尝试将 scoped 服务添加到 singleton,所有条件都相同,只是 AddSingleton

services.AddSingleton<IVMValidationManager, VMValidationManager>();
services.AddHostedService<Worker>();

有很多关于此的文档..但是从 Service lifetimes

Do not resolve a scoped service from a singleton and be careful not to do so indirectly, for example, through a transient service. It may cause the service to have incorrect state when processing subsequent requests. It's fine to:

  • Resolve a singleton service from a scoped or transient service.
  • Resolve a scoped service from another scoped or transient service.