I'm trying to set up Hangfire to execute a method in a service on a recurring basis. However, the AutoFac is complaining that the service is not registered:
program.cs
var serviceCollection = new ServiceCollection()
.AddScoped<BlobService>()
.AddSingleton<IConfiguration>(configuration)
.AddDbContext<RedactedDbContext>(opt =>
{
opt.UseNpgsql(connectionString);
})
.AddScoped<ActivityChangeInfoCh>()
.AddScoped<SpecificConditionsCh>()
.AddScoped<CardIdentificationCh>()
.AddScoped<UploadInfoCh>()
.AddScoped<CardEventDataCh>()
.AddScoped<CardFaultDataCh>()
.AddScoped<CardVehiclesUsedCh>()
.AddScoped<GNSSPlacesCh>()
.AddScoped<HangfireService>()
.AddTransient<FileReader>()
.AddScoped<ExplorerService>()
.AddScoped<DriverFileService>();
GlobalConfiguration.Configuration
.SetDataCompatibilityLevel(CompatibilityLevel.Version_180)
.UseSimpleAssemblyNameTypeSerializer()
.UseColouredConsoleLogProvider()
.UseRecommendedSerializerSettings()
.UsePostgreSqlStorage(config.GetConnectionString("Hangfire"))
.UseAutofacActivator(builder.Build());
var serviceProvider = serviceCollection.BuildServiceProvider();
DriverFileService driverFileService = serviceProvider.GetService<DriverFileService>();
driverFileService.TestAvailability();
var options = new BackgroundJobServerOptions { WorkerCount = 1 };
using (var server = new BackgroundJobServer(options))
{
Console.WriteLine("Hangfire Server started. Press any key to exit...");
var manager = new RecurringJobManager();
manager.AddOrUpdate(
"process2",
() => serviceProvider.GetService<DriverFileService>().Test(),
"*/50 * * * * *"
);
Console.ReadKey();
}
As you can see this code works:
driverFileService.TestAvailability();
however the code inside the backgroundjobserver
complains about unregistered services
ERROR:
2024-02-08 07:10:35 [INFO] (Hangfire.PostgreSql.PostgreSqlStorage) Start installing Hangfire SQL objects...
2024-02-08 07:10:35 [INFO] (Hangfire.PostgreSql.PostgreSqlStorage) Hangfire SQL objects installed.
Removing recurring jobs....
Removing recurring jobs in connection....
CONNECTION: Hangfire.PostgreSql.PostgreSqlConnection
JOBS: 0
Started DriverFileService: TestAvailability()
Exiting DriverFileService: TestAvailability()
2024-02-08 07:10:35 [INFO] (Hangfire.BackgroundJobServer) Starting Hangfire Server using job storage: 'PostgreSQL Server: Host: redacted.postgres.database.azure.com, DB: hangfire_development, Schema: hangfire'
2024-02-08 07:10:35 [INFO] (Hangfire.BackgroundJobServer) Using the following options for SQL Server job storage:
2024-02-08 07:10:35 [INFO] (Hangfire.BackgroundJobServer) Queue poll interval: 00:00:15.
2024-02-08 07:10:35 [INFO] (Hangfire.BackgroundJobServer) Invisibility timeout: 00:30:00.
2024-02-08 07:10:35 [INFO] (Hangfire.BackgroundJobServer) Using the following options for Hangfire Server:
Worker count: 1
Listening queues: 'default'
Shutdown timeout: 00:00:15
Schedule polling interval: 00:00:15
Hangfire Server started. Press any key to exit...
2024-02-08 07:10:35 [INFO] (Hangfire.Server.BackgroundServerProcess) Server stianhave:261704:bb1c7ac3 successfully announced in 13.4146 ms
2024-02-08 07:10:35 [INFO] (Hangfire.Server.BackgroundServerProcess) Server stianhave:261704:bb1c7ac3 is starting the registered dispatchers: ServerWatchdog, ServerJobCancellationWatcher, ExpirationManager, CountersAggregator, Worker, DelayedJobScheduler, RecurringJobScheduler...
2024-02-08 07:10:36 [INFO] (Hangfire.Server.ServerWatchdog) 4 servers were removed due to timeout
2024-02-08 07:10:36 [INFO] (Hangfire.Server.BackgroundServerProcess) Server stianhave:261704:bb1c7ac3 all the dispatchers started
2024-02-08 07:10:51 [WARN] (Hangfire.AutomaticRetryAttribute) Failed to process the job '2171': an exception occurred. Retry attempt 1 of 10 will be performed in 00:00:18.
Autofac.Core.Registration.ComponentNotRegisteredException
The requested service 'Redacted.Services.DriverFileService' has not been registered. To avoid this exception, either register a component to provide the service, check for service registration using IsRegistered(), or use the ResolveOptional() method to resolve an optional dependency.
at Autofac.ResolutionExtensions.ResolveService(IComponentContext context, Service service, IEnumerable`1 parameters)
at Autofac.ResolutionExtensions.Resolve(IComponentContext context, Type serviceType, IEnumerable`1 parameters)
at Autofac.ResolutionExtensions.Resolve(IComponentContext context, Type serviceType)
at Hangfire.AutofacJobActivator.AutofacScope.Resolve(Type type) in C:\projects\hangfire-autofac\src\Hangfire.Autofac\AutofacJobActivator.cs:line 69
at Hangfire.Server.CoreBackgroundJobPerformer.Perform(PerformContext context)
at Hangfire.Server.BackgroundJobPerformer.<>c__DisplayClass10_0.<PerformJobWithFilters>b__0()
at Hangfire.Server.BackgroundJobPerformer.InvokePerformFilter(IServerFilter filter, PerformingContext preContext, Func`1 continuation)
at Hangfire.Server.BackgroundJobPerformer.<>c__DisplayClass10_1.<PerformJobWithFilters>b__2()
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, BackgroundJob backgroundJob, IReadOnlyDictionary`2& customData)
2024-02-08 07:11:06 [WARN] (Hangfire.AutomaticRetryAttribute) Failed to process the job '2172': an exception occurred. Retry attempt 1 of 10 will be performed in 00:00:37.
DriverFileService.cs
public DriverFileService(
ExplorerService explorerService,
ActivityChangeInfoCh aciCh,
SpecificConditionsCh scCh,
CardIdentificationCh ciCh,
UploadInfoCh uiCh,
CardEventDataCh cedCh,
CardFaultDataCh cfdCh,
CardVehiclesUsedCh cvuCh,
GNSSPlacesCh gnssCh
)
{
this.explorerService = explorerService;
this.aciCh = aciCh;
this.scCh = scCh;
this.ciCh = ciCh;
this.uiCh = uiCh;
this.cedCh = cedCh;
this.cfdCh = cfdCh;
this.cvuCh = cvuCh;
this.gnssCh = gnssCh;
}
public void UploadFileContent(DriverFileInfo file) { }
public void TestAvailability()
{
System.Console.WriteLine("Started DriverFileService: TestAvailability()");
System.Console.WriteLine("Exiting DriverFileService: TestAvailability()");
}
public void Test()
{
System.Console.WriteLine("Started DriverFileService: Test()");
List<DriverFileInfo> files = explorerService.GetFiles();
System.Console.WriteLine("Exiting DriverFileService: Test()");
}
After reading @J.Memisevic's answers I read up on the documentation. Turns out my registration of autoFac was not set correctly:
1. register services
2. Set configuration
3. use lifetime scope and use instances
References: