Exception while using logger in background job (ASP.NET Core / Serilog)

serialization
ioc-container
aspnetcore
logging
Tags: #<Tag:0x00007f69fd834d48> #<Tag:0x00007f69fd834b18> #<Tag:0x00007f69fd8347d0> #<Tag:0x00007f69fd8345f0>

#1

Hi,

I’m having problems using the logger in the context of a fire-and-forget background job with ASP.NET Core WebApi.
When using logger.LogInformation(“some message”). The following exception occurs:

Newtonsoft.Json.JsonSerializationException: Could not create an instance of type Microsoft.Extensions.Logging.ILogger. Type is an interface or abstract class and cannot be instantiated. Path ‘’, line 1, position 2.

Obvisouly, it seems that hangfire is unable to resolve the instantion of the logger based on the parameters instructed in the application’s bootstrap.

I am certain that:

  • Hangfire is properly configured and works
  • The logger (using Serilog) works when used in the same scope as the app (not in backgorund)
  • Service injection works for background jobs for other services than the ILogger

Here is my configuration:

Program.cs

public static IWebHost BuildWebHost (string[] args) =>
                WebHost.CreateDefaultBuilder (args)
                .UseStartup<Startup> ()
                .UseSerilog ()
                .Build ();

Startup.cs

public Startup (IHostingEnvironment env) {
              Log.Logger = new LoggerConfiguration ()
                .MinimumLevel.Debug ()
                .MinimumLevel.Override ("Microsoft", LogEventLevel.Information)
                .Enrich.FromLogContext ()
                .WriteTo.Console ()
                .WriteTo.Debug ()
                .WriteTo.RollingFile (System.IO.Path.Combine ("logs/{Date}-logs.txt"))
                .CreateLogger ();
        }

public void ConfigureServices (IServiceCollection services) {
    services.AddLogging(loggingBuilder => loggingBuilder.AddSerilog(dispose: true));
    // ... registering other services
    services.AddMvc ();
    services.AddHangfire (conf => conf.UseSqlServerStorage (Configuration.GetConnectionString ("HangFire")));
}

public void Configure (IApplicationBuilder app, IHostingEnvironment env, IServiceProvider serviceProvider) {
            app.UseMvc ();

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

HangfireActivator

public class HangfireActivator : Hangfire.JobActivator {
        private readonly IServiceProvider _serviceProvider;

        public HangfireActivator (IServiceProvider serviceProvider) {
            _serviceProvider = serviceProvider;
        }

        public override object ActivateJob (Type type) {
            Debug.WriteLine("ActivateJob() => " + type.Name);
            return _serviceProvider.GetService (type);
        }
}

ValueController.cs

public class ValuesController : Controller {

        private readonly ILogger<ValuesController> logger;
        private readonly SomeService someService;

        public ValuesController (ILogger<ValuesController> logger, SomeService someService) {
            this.logger = logger;
            this.someService = someService;
        }

        [Route ("task")]
        public  JsonResult StartTask () {
            var server = new BackgroundJobServer ();
            BackgroundJob.Enqueue(() => logger.LogInformation("HELLO from background job instanciated logger"));
            return new JsonResult (new { Result = "task started" });
        }
}

Am I missing something ?
Any help or link to a related topic would be much appreciated. Thank you for your help !


#2

I’m having the same issue as well, and I don’t actually hit the breakpoint or Debug.WriteLine in HangfireActivator.ActivateJob, so kinda hard to actually diagnose further.