
Wolverine
Implementing event driven architecture using Wolverine
What is it?
Wolverine is a package targeting .Net core 6 and 7 that provides the tooling to implement a mediator pattern and/or message bus with minimal code.
What is the Mediator Pattern?
The mediator pattern has existed for a while and is mentioned in “Design Patterns: Elements of Reusable Object-Oriented Software” book published in 1994, so the theory has been around for almost 3 decades. By following this pattern an object can be defined that encapsulates how a set of objects interact.
In layman's terms if we had 2 objects such as a chatroom and its participants, Rather than communicating directly with each other (participant -> chatroom) which requires the chatroom to have references to all participants and vice versa. We could follow this pattern and encapsulate those objects and introduce a chatroom mediator which would handle the communicating.
This may sound like it's adding an extra step, however what this does is decouple participant and chatroom from each other meaning that if the data or functionality for either of those objects were to change the other wouldn't be affected, however if the communication between them needs to be changed this can be done via the mediator. Additionally because the objects are now also encapsulated they only retain data/functionality that is necessary for that object.

What is a Message Bus?
A message bus is very similar to the mediator pattern however it takes it a whole step further by being more generic, following from the example above the mediator is specific for the chatroom and participants whereas the message bus caters for communication between any object.
At its core a message bus allows an object to send a ‘message’ and if there are any listeners/subscribers to that type of message then they will handle it.
Message bus has become synonymous with microservices as it is a key component when communicating between different services, however a message bus can be used to implement event driven communication in a single service.

So… why Wolverine?
During development for our well-being and mindfulness client it became apparent that the majority of the functionality is event driven and would make sense to implement an event driven pattern. We first looked into what it would take to implement a publisher/subscriber pattern but managing all the publishers and subscribers could be cumbersome so rather than reinventing the wheel we looked at what was out there.
We first came across MessagePipe with its main selling point being its fast performance, however this appeared to be a replacement for existing functionality but we would still need to manage subscribers and publishers.
We then came across Wolverine in the pod cast ”.Net Rocks!”, Whilst fairly new there was enough documentation to get started.
First impressions: It's incredibly easy to get started with, Wolverine does a lot of the heavy lifting. However this raised a few questions about how it works, Is there too much magic going on? Magic tends to have bad connotations as it hides the true behaviour of said task/functionality. Following from this we sought out to find what Wolverine does and how it does it, luckily their documentation covers parts of this.
In essence Wolverine finds objects based on some criteria such as an object called a ‘Handler’ it then wraps these objects with another object that Wolverine utilises to execute the message bus functionality. It's important to note that this ‘wrapping’ occurs during runtime and does not use Reflection so there is no loss in performance.
Keywords
- Object - an object is an entity that has data and/or functionality
- Encapsulate - hide data/functionality that is not necessary to other objects
- Loose/tight coupling - describes relationships between objects
- Magic - in programming magic often refers to the hiding of complex code/functionality
- Reflection - Methods in which an application can collect information about itself and manipulate it, low performance.
Sources
Wolverine - https://wolverine.netlify.app/
MessagePipe - https://github.com/Cysharp/MessagePipe
.Net Rocks - https://www.dotnetrocks.com/
Extras/Code snippets
Configuration
Add Wolverine to IHostBuilder
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureUmbracoDefaults()
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStaticWebAssets();
webBuilder.UseStartup<Startup>();
})
.UseWolverine(); // add this
Handler + message
Creating a message and a handler which processes the message
public record Sleep(string SomeParameter); // define a message
public class SleepHandler // define a handler
{
public async Task Handle(Sleep sleep) // message as first parameter
{
Debug.WriteLine(sleep.SomeParameter);
Thread.Sleep(new TimeSpan(0,1,0));
}
}
Usage
Inject Wolverines IMessageBus to publish the message
public class SomeClass : ISomeClass
{
private readonly IMessageBus _messageBus;
public SomeClass(IMessageBus messageBus)
{
_messageBus = messageBus;
}
public async Task Sleep()
{
await _messageBus.PublishAsync(new Sleep("Zzz"));
}
}

Let's make something great together.
Ready to start your next project? Oliver is available to talk through your needs and how we can help.
Get in Touch