Unable to resolve service for type x while attempting to activate y

I have an ASP.NET core 2.1 web application that needs to run recurring task. So I installed Hangfire 1.6.20 with nuget. Then I created a class to register a hangfire task:

public class HFStarter
{
    private MyFirstService _mfs;

    public HFStarter(MyFirstService mfs)
    {
        _mfs = mfs;
    }

    public void Run(Hangfire.IJobCancellationToken cancellationToken)
    {
        cancellationToken.ThrowIfCancellationRequested();
    }

}

HFStarter depends on another class called MyFirstService:

public class MyFirstService
{
}

Then I set up my Startup class like this:

public class Startup
{
    private IConfiguration _configuration;
    private IServiceScopeFactory _serviceScopeFactory;

    public Startup(IConfiguration c, IServiceScopeFactory ssf)
    {
        _configuration = c;
        _serviceScopeFactory = ssf;
    }

    public void ConfigureServices(IServiceCollection services)
    {
        var connstr = _configuration.GetConnectionString("DefaultConnection");

        services.AddSingleton<MyFirstService>();

        services.AddMvc();
        services.AddHangfire(hf => hf
            .UseSqlServerStorage(connstr)
            .UseActivator(new Hangfire.AspNetCore.AspNetCoreJobActivator(_serviceScopeFactory)));
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseMvc();
        app.UseHangfireServer();
        app.UseHangfireDashboard();

        RegisterHangfireTasks();
    }

    private void RegisterHangfireTasks()
    {
        RecurringJob.AddOrUpdate<HFStarter>(
            "a",
            s => s.Run(JobCancellationToken.Null),
            "0 21 * * *",
            TimeZoneInfo.Utc);
    }

}

I registered MyFirstService into the IoC container in the ConfigureServices. For job activator I use the built-in Hangfire.AspNetCore.AspNetCoreJobActivator. Then I register the task using the generics: RecurringJob.AddOrUpdate<HFStarter>().

When I run the application, I see in Hangfire dashboard that the task failed to run with an exception:

Unable to resolve service for type ‘CobaHangfire.MyFirstService’ while attempting to activate ‘CobaHangfire.HFStarter’.
at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.ConstructorMatcher.CreateInstance(IServiceProvider provider)
at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.CreateInstance(IServiceProvider provider, Type instanceType, Object[] parameters)
at Hangfire.Server.CoreBackgroundJobPerformer.Perform(PerformContext context)
at Hangfire.Server.BackgroundJobPerformer.<>c__DisplayClass8_0.b__0()
at Hangfire.Server.BackgroundJobPerformer.InvokePerformFilter(IServerFilter filter, PerformingContext preContext, Func`1 continuation)
at Hangfire.Server.BackgroundJobPerformer.PerformJobWithFilters(PerformContext context, IEnumerable`1 filters)
at Hangfire.Server.BackgroundJobPerformer.Perform(PerformContext context)
at Hangfire.Server.Worker.PerformJob(BackgroundProcessContext context, IStorageConnection connection, String jobId)

What did I do wrong?

OK I figured out the issue: AspNetCoreJobActivator is already registered so I don’t have to register it again. When I register it again, it stops working.

So I change this line:

services.AddHangfire(hf => hf
    .UseSqlServerStorage(connstr)
    .UseActivator(new Hangfire.AspNetCore.AspNetCoreJobActivator(_serviceScopeFactory)));

to:

services.AddHangfire(hf => hf
    .UseSqlServerStorage(connstr));

and then HFStarter resolves correctly.

I got the same random exceptions.

System.InvalidOperationException (893FB6B5D0C7:1
893fb6b5d0c7:1:307e8406-5bd4-4691-ab3f-b5dfc083d9fb
)
Unable to resolve service for type 'MediatR.IMediator'

Some job fails, some not. When auto-retrying job might get finished, might not. I am not sure how to debug this. I am using .net 6.0

Since no one is here - seems like fixed issue with using IServiceScopeFactory to resolve dependencies inside job method.

public class TestJob
{
    private readonly IServiceScopeFactory _scopeFactory;

    public TestJob(IServiceScopeFactory scopeFactory)
    {
        _scopeFactory = scopeFactory;
    }

    public async Task Process(CancellationToken cancellationToken)
    {
        using var scope = _scopeFactory.CreateScope();
        var mediator = scope.ServiceProvider.GetRequiredService<IMediator>();

		// job logic
    }
}