2021-03-31

How to configure Hangfire with Autofac in a dotnet core console app

I'm trying to port a working Hangfire setup embedded in a Kestrel webserver to a console app. I've modified the web app so it still provides the Hangfire dashboard but doesn't start its own Hangfire server.

The code I must port uses Autofac. I've added the Hangfire.Autofac package to the console app and have already performed all the steps detailed in the answer to Hangfire Autofac .net core 3.1

When I create a job (using the web app) the console app Hangfire server tries to execute the job but I get this failure message:

The requested service 'AED.ServicesLayer.JobProcessing.ProcessManager' has not been registered.

Investigating this we examine the setup of Autofac in the console app. This is how I set up my container.

IConfiguration config = new ConfigurationBuilder()
  .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
  .Build();
var containerBuilder = new Autofac.ContainerBuilder();
containerBuilder.RegisterInstance(Log.Logger).AsImplementedInterfaces();
containerBuilder.RegisterModule(new RepositoryModule(config));
containerBuilder.RegisterType<UserService>().As<IUserService>();
containerBuilder.RegisterInstance(config).As<IConfiguration>();
containerBuilder.RegisterModule(new JobProcessingModule(config));
var container = containerBuilder.Build();

When the app is executed, hitting a breakpoint in JobProcessingModule proves the following line of code is executed.

builder.RegisterType<ProcessManager>().As<IProcessManager>();

It is very curious that the containerBuilder instance passed to JobProcessingModule.Load(containerBuilder) is not the same containerBuilder object on which RegisterModule is invoked.

However, experiments with simplified injectables suggest that this is normal, and the injected items are nevertheless visible in the registrations for the container that is returned.

Re-examining the logged failure we note that the class is mentioned by class name and not by interface. Changing the registration by removing the interface registration, like so

builder.RegisterType<ProcessManager>();//.As<IProcessManager>();

caused the ProcessManager to be found in the Hangfire console host but caused run-time errors in the web application when creating the job.

Registering it both ways caused ProcessManager to be found by both, with a new problem surfacing: cannot resolve dependencies. This, however, is merely a new case of the same problem.

While this allows me to move forward with getting a console host working, I do not like code I do not understand. Why should the console host require registration by class name when the web app does not?

Whatever is causing this has also caused Hangfire.IBackgroundJobClient to fail to resolve to the background job client. This is a hangfire class so it really does seem like there is a fundamental problem.



from Recent Questions - Stack Overflow https://ift.tt/3stqiwK
https://ift.tt/eA8V8J

No comments:

Post a Comment