Reputation: 2794
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:
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.
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()");
}
Upvotes: 0
Views: 453
Reputation: 2794
After reading @J.Memisevic's answers I read up on the documentation. Turns out my registration of autoFac was not set correctly:
string baseDirectory = Directory.GetParent(AppContext.BaseDirectory).Parent.Parent.FullName;
Log.Logger = new LoggerConfiguration().WriteTo
.Console()
.WriteTo.File(Path.Combine(baseDirectory, "logs/logfile.txt"))
.CreateLogger();
var loggerFactory = LoggerFactory.Create(builder =>
{
builder.AddSerilog();
builder.AddConsole();
});
builder.RegisterInstance(loggerFactory).As<ILoggerFactory>().SingleInstance();
builder.RegisterGeneric(typeof(CustomLogger<>)).AsSelf().SingleInstance();
builder.RegisterGeneric(typeof(Logger<>)).As(typeof(ILogger<>)).SingleInstance();
var container = builder.Build();
GlobalConfiguration.Configuration
.SetDataCompatibilityLevel(CompatibilityLevel.Version_180)
.UseSimpleAssemblyNameTypeSerializer()
.UseColouredConsoleLogProvider()
.UseRecommendedSerializerSettings()
.UsePostgreSqlStorage(config.GetConnectionString("Hangfire"))
.UseAutofacActivator(container);
using (var scope = container.BeginLifetimeScope())
{
var driverFileService = scope.Resolve<DriverFileService>();
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();
driverFileService.TestAvailability();
manager.AddOrUpdate("process4", () => driverFileService.Test(), "*/50 * * * * *");
Console.ReadKey();
}
}
References:
Upvotes: 0
Reputation: 1454
Insted of :
manager.AddOrUpdate(
"process2",
() => serviceProvider.GetService<DriverFileService>().Test(),
"*/50 * * * * *"
);
Can you try :
RecurringJob.AddOrUpdate<DriverFileService>( "process2", job => job.Test(), "*/50 * * * * *");
Upvotes: 0
Reputation: 1454
Recuring job manager just saves job definition to database. JobActivator
is resposible for creating an instance of the job. If you are using Autofac
as DI you gonna need to setup JobActivator, you can use Hangife.Autofac
var builder = new ContainerBuilder();
// builder.Register...
GlobalConfiguration.Configuration.UseAutofacActivator(builder.Build());
GlobalConfiguration.Configuration.UseAutofacActivator(builder.Build());
Upvotes: 1