I’ve been using MediatR and Hangfire independently for awhile. I’ve previously posted one solution on how you could use send Commands with MediatR and Hangfire. The solution I had come up with in that post was to get around the expression serialization issue with type parameters in MediatR’s Send<T>.
Sponsor: Do you build complex software systems? See how NServiceBus makes it easier to design, build, and manage software systems that use message queues to achieve loose coupling. Get started for free.
IRequest<Unit>Because we are creating a a fire and forget command which will be run in the background, there will be no return value. MediatR handles these types of requests by using the Unit type. When creating a command you will implement IRequest and your request handler will implement IRequestHandler<IRequest, Unit>. To send MyCommand you would use MediatR’s Send<T>() where T is the response of the request, in our case Unit.
FeedbackIn my original post, Darren Cauthon made some suggestions that got me thinking about how I could create a better solution to integrate MediatR and Hangfire a bit better.
ExtensionsMy first task was to create an extension method on MediatR that would Enqueue a command to Hangfire. I took a similar approach to my previous solution by wrapping MediatR’s Send<T>() in a method with no type parameters. In order for the HangfireMediator class to be instantiated, Hangfire provides
JobActivatorclass to instantiate the target types before invoking instance methods. Finally, we need to configure Hangfire to use the new Activator as well as configure Json.NET to include type information when serializing. Here we an create an extension method on Hangfires IGlobalConfiguration in order to use our new activator.
3 thoughts to “Background Commands with MediatR and Hangfire”
I’ve been using a different approach to integrate MediatR and Hangfire (storing the command json in the database which Hangfire executed by Id) but I like this approach using the JobActivator much better, thanks for the post!
Yes, what you described is defined as a best practice. I think I’m going to test that approach as well.