I have an application that contains multiple web api projects in .net. I am using MongoDb. Now I want to add a common hangfire to this application. In other words, there will be a single hangfire db and all web api projects will manage jobs through this db. For this, I added an extension to my common class library.
Common/HangfireExtensions.cs
public static class HangfireExtensions
{
public static IServiceCollection AddHangfireServices(this IServiceCollection services, string mongoConnectionString, string dbName, string projectName)
{
GlobalJobFilters.Filters.Add(new AppJobFilterAttribute(projectName));
services.AddHangfire(config =>
{
config.UseMongoStorage(mongoConnectionString, dbName, new MongoStorageOptions
{
MigrationOptions = new MongoMigrationOptions
{
MigrationStrategy = new MigrateMongoMigrationStrategy(),
BackupStrategy = new NoneMongoBackupStrategy()
},
CheckConnection = true,
CheckQueuedJobsStrategy = CheckQueuedJobsStrategy.TailNotificationsCollection
});
});
services.AddHangfireServer(options =>
{
options.Queues = new[] { Constants.AppNumber.ToString() };
});
return services;
}
}
Here, by using filter, I wanted each web API project to run the jobs I defined in it. But even though I use the filter, I still get an error like this because the web API projects are trying to run jobs that are not defined in other projects:
Recurring job 'AJobAsync' can't be scheduled due to an error and will be disabled. Hangfire.Common.JobLoadException: Could not load the job. See inner exception for the details. ---> System.IO.FileNotFoundException: Could not load file or assembly 'A.API, Culture=neutral, PublicKeyToken=null'. The system cannot find the file specified.
My codes in projects A and B are as follows:
A.API/Program.cs
builder.Services.AddHangfireServices(connectionString, hangfireDatabase, "A.API");
app.UseHangfireDashboard();
var jobService = app.Services.GetRequiredService<IJobService>();
RecurringJobs.Initialize(jobService);
A.API/RecurringJobs.cs
public static class RecurringJobs
{
public static void Initialize(IJobService service)
{
RecurringJob.RemoveIfExists(nameof(service.AJobAsync));
RecurringJob.AddOrUpdate(
recurringJobId: nameof(service.AJobAsync),
methodCall: () => service.AJobAsync(),
cronExpression: "0 */1 * ? * *", // Every 1 minute
queue: Constants.AppNumber.ToString()
);
}
}
A.API/IJobService.cs
public interface IJobService
{
Task AJobAsync();
}
Assume that there is a B.API in this structure as well. It also has specific jobs defined for it.
When these two projects run at the same time, I get the error I mentioned above because it tries to run the jobs defined in both of them. My request is that only project A should run the jobs defined in project A, and only project B should run the jobs defined in project B.
1