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.
In my previous post, I created a few extension methods for Hangfire and MediatR in order to enqueue an IRequest. However, it was not following Hangfire Best Practice.
The purpose was to have the IRequest serialized entirely when calling Enqueue(), which would be stored in Hangfires storage.
Then when the request would be invoked, Hangfire would deserialize the IRequest and call Mediators Send().
My functioning example worked as expected. However, Hangfire recommends making your job arguments small and simple.
Best Practice
Method invocation (i.e. a job) is serialized during the background job creation process. Arguments are converted into JSON strings using the TypeConverter class. If you have complex entities and/or large objects; including arrays, it is better to place them into a database, and then pass only their identities to the background job. Instead of doing this:Consider doing this:public void Method(Entity entity) { }
public void Method(int entityId) { }
New Process
I liked my initial approach using extension methods and using the Hangfire’s JobActivator in order to construct the class that will be sending the Request to MediatR. Using the best practice the changes needed would be:- Pass a database connection factory to the Hangfire Configuration extension method (UseMediatr)
- Create a new MediatR extension method to pass a CommandId and the Request
- Insert a new record into a database with the CommandId and serialized Request
- Create a new method that will be invoked by Hangfire when only using the Command
- Select the record out of the database and deserialize the Request
- Send to MediatR
Hangfire Configuration
A database connection factory needs to be passed when configuration MediatR with Hangfire.Enqueue
Now in Enqueue a new command with or without a Command Id.Database
In my working code, I’m creating a table [MediatR.Request] in the Hangfire database automatically which is used to store the serialized commands. Since this is a example, it only contains the CommandId and the serialized command. However, it would likely make send to store the date created as well as when the date the command was invoked and completed by Hangfire.Demo
I’ve published all the Extension methods as well as a demo containing two console applications. One console application is the producer which enqueues commands, while the consumer handles them.
You can find all the source on GitHub
https://github.com/dcomartin/Hangfire.MediatR.Demo