Skip to content

Using Hangfire and MediatR as a Message Dispatcher

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.

Learn more about Software Architecture & Design.
Join thousands of developers getting weekly updates to increase your understanding of software architecture and design concepts.


Two popular libraries in Hangfire and MediatR can be used together to create a pretty powerful out-of-process messaging dispatcher. I’ve covered this a bit many years ago but I figured I’d give it a refresh since it’s a bit easier in the world of ASP.NET Core.

YouTube

Check out my YouTube channel where I post all kinds of content that accompanies my posts including this video showing everything that is in this post.

Hangfire and MediatR Bridge/Wrapper

The first thing you need to do is create a bridge/wrapper around MediatR. At first this may seem completely pointless, but it has a purpose. Hangfire has a lot extensibility in terms of how jobs are executed that are often times defined by using attributes. Because we don’t own the MediatR library, we need to have our own class that we can defined these attributes on.

Here’s a simple start to our Bridge/Wrapper

In the example above, I have an overload for Send() that accepts the jobName as the first parameter. The DisplayName attribute will be used by Hangfire to show in the UI Dashboard the name of the job. This is a simple example of why we need this wrapper.

MediatR Extensions

The next piece of the puzzle is creating extension methods to be able to use Hangfire to create background jobs. In the example below I’ve created Enqueue() extension methods that use the Hangfire BackgroundJobClient to enqueue work using our Bridge/Wrapper

Hangfire Serialization

In the BackgroundJobClient.Enqueue() above, Hangfire will use Json.NET to serialize the IRequest that we are passing to Send() that ultimately gets put into storage. When Hangfire then pulls that job out of storage to perform the work, it needs to deserialize it. Because it’s just an IRequest it has no way to turning that into a concrete type.

To handle this, we need to configure Hangfire to add type handling when it serializes/deserializes.

ConfigureServices

The last thing we need to do is actually configure Hangfire in the ConfigureServices of either your ASP.NET Core Startup or your HostBuilder.

Here’s an example of my Worker process. This is just a console app that is purely a Hangfire server that just processes jobs from Hangfire.

Enqueuing a Request

In order to enqueue a MediatR request to Hangfire is a matter of calling the Enqueue() extension method we created off of IMediator.

In the example above, the HTTP Request to our Controller action will return a 204 NoContent, even though we are throwing in our PlaceOrderHandler because it’s execution is actually done out of the context of the HTTP Request. This could either be in a different thread, an entire different process, or on a totally on a different server).

More

There’s a lot more you can do with this and take it much farther to handle things like event publishing to have each event handler be it’s own job within Hangfire.

You can get all the source code of this running example on my GitHub.

If you have any thoughts or questions, please leave a comment on my blog, Twitter, or on the YouTube video.

Learn more about Software Architecture & Design.
Join thousands of developers getting weekly updates to increase your understanding of software architecture and design concepts.


Links

Leave a Reply

Your email address will not be published. Required fields are marked *