Error: Hangfire Job Will Fail randomly and then succeed while using dependency injection

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

#1

Hello,

I recently added an IoC container to my Hangfire jobs and I noticed that now when my jobs get enqueued they will either succeed on the first run or fail multiple times before randomly succeeding. Every time it fails I get the same exception: System.MissingMethodException: Cannot create an instance of an interface.

It almost seems like the JobActivator doesn’t know how to inject my services but then suddenly can and will run the job successfully.

As far as my code goes I am doing the following in my ConfigureServices method:

services.AddScoped<IAPIHandler, APIHandler>();

Then in my Configure method:

GlobalConfiguration.Configuration.UseActivator(new HangfireActivator(serviceProvider)); app.UseHangfireServer();
app.UseHangfireDashboard();

Where my HangfireActivator is my IoC container using the default .NET core service provider.

When I enqueue the job I am doing the following:

jobId = _client.Enqueue(() => newJob.Invoke(null, job.Properties));

I am running my Hangfire client as a Windows service and there is only one instance of my Hangfire client. I am also using the latest version of Hangfire (1.6.20). My job storage is using Couchbase. Any advice would be appreciated.


#2

I have solved this issue. I learned two things:

The first is that in .NET Core, Hangfire provides a AspNetCoreJobActivator class. You can use this to replace the default JobActivator class and use the .NET Core IServiceProvider instead.

The second thing is that my Windows Service was creating a new BackGroundJobServer which was then starting my Hangfire server client.

I had to use the following in my code:

BackgroundJobServerOptions serverOptions = new BackgroundJobServerOptions()
{
     // ...

    Activator = new AspNetCoreJobActivator(_serviceProvider.GetService<IServiceScopeFactory>())
};

I override my Job Activator here and provide it the IServiceScopeFactory from my current IServiceProvider.

After that, all of my services were added in my standard Startup.cs file and now I am having no issues with my jobs running.