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

ioc-container
Tags: #<Tag:0x00007f7596a0b640>

#1

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?


#2

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.