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

Time:11-01

I am creating C# worker process and having trouble defining dependency.

I have a class called VMValidationManager which implements interface IVMValidationManager

public interface IVMValidationManager
{
    void RunVMValidationScripts();
}

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

Also i have Worker class in which i want to inject IVMValidationManager

public class Worker : BackgroundService
{
    private readonly IVMValidationManager _vmValidationManager;

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


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

In Program.cs i have this code

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>();
        });
}

When run i am getting error. stack trace

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)

What am i doing wrong?

CodePudding user response:

You are trying to add a scoped service to a singleton, all things being equal, just AddSingleton

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

There is lots of documentation on this.. however start with 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.
  • Related