At some point in your .NET journey, you’ve probably worked with libraries like MediatR, MassTransit, or CAP for handling messaging and commands. Each has its strengths, but sometimes the wiring and configuration get in the way of just building features.
Recently, I discovered Wolverine, a command and message bus library from the JasperFx team. It brings together CQRS, messaging, scheduled jobs, and durable inbox/outbox all in one sleek package. And the best part? It’s fast, clean, and fun to work with.
In this article, I’ll walk you through a simple console application that demonstrates how to use Wolverine to handle commands, publish events, and schedule background messages, all without requiring a database or web API.
Why Wolverine?
Wolverine aims to simplify distributed application architecture by combining.
- Command handling (like MediatR).
- Asynchronous and scheduled messaging.
- Built-in middleware and behaviors.
- Optional durable inbox/outbox with Marten (PostgreSQL).
Instead of bolting together multiple libraries, Wolverine gives you a unified model with batteries included.
The Example: Console-Based User Registration
We’ll build a console app that,
- Registers a user via a command.
- Sends a welcome email (simulated).
- Schedules a follow-up reminder message.
Everything runs in-process using Wolverine's local message bus.
Step 1. Create the Project
Project Folder Structure
WolverineConsoleDemo/
├── Program.cs
├── WolverineConsoleDemo.csproj
├── Messages/
│ ├── RegisterUser.cs
│ ├── UserRegistered.cs
│ └── RemindAdmin.cs
├── Handlers/
│ ├── RegisterUserHandler.cs
│ ├── UserRegisteredHandler.cs
│ └── RemindAdminHandler.cs
dotnet new console -n WolverineConsoleDemo
cd WolverineConsoleDemo
dotnet add package WolverineFx
Step 2. Define Messages and Handlers
RegisterUser.cs
public record RegisterUser(string Email, string FullName);
UserRegistered.cs
public record UserRegistered(string Email);
RemindAdmin.cs
public record RemindAdmin(string Email);
Step 3. Implement Handlers
RegisterUserHandler.cs
using Wolverine;
using WolverineConsoleDemo.Messages;
namespace WolverineConsoleDemo.Handlers
{
public class RegisterUserHandler
{
/// <summary>
/// Handles the specified command.
/// </summary>
/// <param name="command">The command.</param>
/// <param name="context">The context.</param>
public static async Task Handle(RegisterUser command, IMessageContext context)
{
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine($"Registered: {command.FullName}");
Console.ResetColor();
await context.PublishAsync(new UserRegistered(command.Email));
await context.ScheduleAsync(new RemindAdmin(command.Email), TimeSpan.FromSeconds(10));
}
}
}


Join the conversation! Your thoughts help the community grow.