I would use the command pattern to schedule a generic job that dispatches your actual job which wraps it in your own pre/post invocation logic. This way you can do whatever you want before and after each job execution.
example here are the basic interfaces I use
public interface ICommand
{
string RecurringJobId { get; set; }
}
public interface ICommandDispatcher
{
Task DispatchAsync<TParameter>(TParameter command) where TParameter : ICommand;
}
public interface ICommandHandler<in TParameter> where TParameter : ICommand
{
Task ExecuteAsync(TParameter command);
}
So you can implement a JobDispiatcher
like this
public class JobDispatcher : ICommandDispatcher
{
private readonly IServiceProvider _service;
public JobDispatcher(IServiceProvider service)
{
_service = service;
}
public Task DispatchAsync<TParameter>(TParameter command) where TParameter : ICommand
{
var handler = _service.GetService<ICommandHandler<TParameter>>();
// you can put whatever "pre invoke" logic here , you could even decide not to fire the execution
// of the command if you wanted to
return handler.ExecuteAsync(command);
// you can place any "post invoke" logic here
// e.g schedule another task, etc
}
}
So lets say you had a command that Writes Hello to the Console
public class WriteHelloCommand : ICommand
{
public string FirstName { get; set; }
// this is nice because you have access to the recurring job id when handling the command
public string RecurringJobId { get; set; }
}
public class WriteHelloCommandHandler : ICommandHandler<WriteHelloCommand>
{
public WriteHelloCommandHandler() {
// inject whatever services you need
}
//you can place your Job Filters here to control stuff
[Hangfire.AutomaticRetry(Attempts = 2, DelaysInSeconds = 60)]
protected async Task DoExecuteAsync(WriteHelloCommand command)
{
Console.WriteLine($"JobId = [{command.RecurringJobId}] Hello {command.FirstName}!");
}
}
you register your interfaces like this, (I’m using net core)
services.AddTransient<ICommandDispatcher, JobDispatcher>();
services.AddTransient(typeof(ICommandHandler<WriteHelloCommand>), typeof(WriteHelloCommandHandler));
And do schedule your command like this
string recurringJobId = $"WriteHello[{Guid.NewGuid()}]";
RecurringJob.AddOrUpdate<ICommandDispatcher>(recurringJobId,
d => d.DispatchAsync(new WriteHelloCommand {FirstName = "Bob", RecurringJobId = recurringJobId})
, Cron.Daily);
I copied and pasted this from my project in a rush so It should work, but there may be something i missed.