HangfireIO / HangfireIO/Hangfire
Type Loading Exception in Recurring Job
- Dominant language
- C#
- Stars
- 10.1k
- Forks
- 1.8k
- Avg merge
- 1h 19m
- Merged PRs (30d)
- 1
Description
I'm experiencing a TypeLoadException with a recurring job in Hangfire. The job works fine when triggered manually, but after some time, it fails in the recurring jobs tab with a type loading error.
```
System.InvalidOperationException: Recurring job can't be scheduled, see inner exception for details.
---> Hangfire.Common.JobLoadException: Could not load the job. See inner exception for the details.
---> System.TypeLoadException: Could not load type 'xMessagingAPI.Hangfire.Abstract.Jobs.ICalculateTotalSpendingsJob' from assembly 'xMessagingAPI.Hangfire, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.
at System.Reflection.RuntimeAssembly.g____PInvoke|26_0(QCallAssembly assembly, UInt16* name, Int32 throwOnError, Int32 ignoreCase, ObjectHandleOnStack type, ObjectHandleOnStack keepAlive, ObjectHandleOnStack assemblyLoadContext)
```
**Job Registration**
```c#
services.AddScoped();
RecurringJob.AddOrUpdate("calculate-total-spendings", x => x.RunAsync(), Cron.Minutely );
```
**Hangfire Registration**
```c#
services.AddHangfire((provider, configuration) =>
{
configuration.UseRedisStorage(redis, redisStrogeOptions)
.WithJobExpirationTimeout(TimeSpan.FromDays(30))
.UseSimpleAssemblyNameTypeSerializer()
.UseRecommendedSerializerSettings();
});
JobStorage.Current = new RedisStorage(redis, redisStrogeOptions);
services.AddHangfireServer(configuration =>
{
configuration.WorkerCount = 1;
configuration.Queues = new[]
{
"calculate-spendings", "sync-spendings-with-x", "set-new-balance", "sync-balances-from-x", "spend"
};
});
```
**Interface Definition**
```c#
public interface ICalculateTotalSpendingsJob
{
[AutomaticRetry(Attempts = 0, LogEvents = false, OnAttemptsExceeded = AttemptsExceededAction.Fail)]
[Queue("calculate-spendings")]
[JobDisplayName("Calculate Spendings Job")]
[DisableConcurrentExecution(60)]
public Task RunAsync();
}
```
**Implementation**
```c#
public class CalculateTotalSpendingsJob : ICalculateTotalSpendingsJob
{
private readonly IUnitOfWork _unitOfWork;
private readonly IMessageReadRepository _messageReadRepository;
private readonly IMessageWriteRepository _messageWriteRepository;
private readonly IUserService _userService;
private readonly IJobQueueService _jobQueueService;
private readonly IBalanceService _balanceService;
public CalculateTotalSpendingsJob(IUnitOfWork unitOfWork,
IMessageWriteRepository messageWriteRepository,
IMessageReadRepository messageReadRepository,
IUserService userService,
IJobQueueService jobQueueService,
IBalanceService balanceService)
{
_unitOfWork = unitOfWork;
_messageWriteRepository = messageWriteRepository;
_messageReadRepository = messageReadRepository;
_userService = userService;
_jobQueueService = jobQueueService;
_balanceService = balanceService;
}
public async Task RunAsync()
{
Console.WriteLine("OK-calculate");
return;
}
}
```
**Expected Behavior**:
- The recurring job should continue running at the specified interval (every minute)
- No type loading exceptions should occur
**Actual Behavior**:
- Job works when triggered manually
- After some time, the recurring job fails with a TypeLoadException
- The error suggests it cannot load the interface type, even though the interface exists and is properly defined
**Things I've Already Tried**:
- Verified all assembly references are correct
- Confirmed the interface and implementation are in the correct namespace
- Checked that the DLL is present in the build output directory
- Verified all dependencies are properly registered in DI
- Cleared all recurring jobs and reset the Redis database to ensure there are no stale or conflicting job definitions
**Environment**
- Hangfire Version: 1.8.15
- .NET Core Version: .NET 7.0
- Database: Redis 6.2.11
- OS: Debian GNU/Linux 11 (bullseye)
- Environment: Docker Container
Contributor guide
Research direction
Start with the recurring job registration, Hangfire Redis storage configuration, and the reported TypeLoadException, comparing the manual and recurring execution paths. Reproduce the failure in the stated .NET 7, Hangfire 1.8.15, Redis, and Docker environment, then verify that the recurring job continues running every minute without the type-loading error.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100