Mediatron 1.0.1
dotnet add package Mediatron --version 1.0.1
NuGet\Install-Package Mediatron -Version 1.0.1
<PackageReference Include="Mediatron" Version="1.0.1" />
<PackageVersion Include="Mediatron" Version="1.0.1" />
<PackageReference Include="Mediatron" />
paket add Mediatron --version 1.0.1
#r "nuget: Mediatron, 1.0.1"
#:package Mediatron@1.0.1
#addin nuget:?package=Mediatron&version=1.0.1
#tool nuget:?package=Mediatron&version=1.0.1
Mediatron
Mediatron is a small, fast, and easy-to-understand mediator library for .NET.
It helps you keep your code clean by separating "what to do" (a request) from "how to do it" (a handler). This pattern is often called CQRS (Command Query Responsibility Segregation), and Mediatron also supports events (Pub/Sub) so different parts of your app can react to something that happened, without knowing about each other.
Think of Mediatron as a post office for your application:
- You write a letter (a request or a notification).
- You hand it to the mediator (the post office).
- The mediator finds the right person (the handler) and delivers it.
- You never need to know who the handler is or where it lives — the mediator takes care of that.
Why would I use this?
Without a mediator, your controllers and services end up calling many other services directly, and everything becomes tightly connected and hard to test.
With Mediatron:
- Your controller only talks to
IMediator. - Each piece of business logic lives in its own small, focused handler class.
- Adding new features means adding a new file, not editing old ones.
- It's easy to unit test each handler on its own.
Features
| Feature | What it means |
|---|---|
| ✅ Zero Bloat | Small codebase, no unnecessary dependencies. |
| ✅ CQRS Support | Send commands and queries with strong typing. |
| ✅ Pub/Sub Notifications | One event can be handled by many listeners at once. |
| ✅ Pipeline Behaviors | Add cross-cutting logic (logging, validation, etc.) around your handlers. |
| ✅ Native DI Integration | Works directly with Microsoft.Extensions.DependencyInjection. |
| ✅ Fully Tested | Covered by unit tests (xUnit, FluentAssertions, NSubstitute). |
| ✅ XML Documented | Full IntelliSense/documentation comments in the source code. |
Requirements
- .NET 10.0 or later
Microsoft.Extensions.DependencyInjection
Installation
Install Mediatron from NuGet using the .NET CLI:
dotnet add package Mediatron
Getting Started
This section walks you through the basics step by step, using a simple "create a product" example.
Step 1 — Register Mediatron
Mediatron scans one assembly (usually your own project) and automatically finds and registers every handler it can find. You only need to do this once, when you set up your app.
using Mediatron;
using Microsoft.Extensions.DependencyInjection;
var builder = WebApplication.CreateBuilder(args);
// Scan the current assembly for handlers and register everything Mediatron needs
builder.Services.AddMediatron(typeof(Program).Assembly);
var app = builder.Build();
Step 2 — Create a Request
A request describes what you want to happen. There are two kinds:
IRequest— "do something", no result expected (like a command that just performs an action).IRequest<TResponse>— "do something and give me a result back".
using Mediatron;
// A request that returns an int (the new product's id)
public record CreateProductCommand(string Name, decimal Price) : IRequest<int>;
Step 3 — Create a Handler
A handler describes how to do it. Every request needs exactly one matching handler.
using Mediatron;
public class CreateProductCommandHandler : IRequestHandler<CreateProductCommand, int>
{
public async Task<int> Handle(CreateProductCommand request, CancellationToken cancellationToken)
{
// Put your business logic here, e.g. save the product to a database
int generatedId = 42;
return await Task.FromResult(generatedId);
}
}
Step 4 — Send the Request
Inject IMediator wherever you need it (for example, in an ASP.NET Core controller) and call SendAsync.
[ApiController]
[Route("api/[controller]")]
public class ProductsController : ControllerBase
{
private readonly IMediator _mediator;
public ProductsController(IMediator mediator)
{
_mediator = mediator;
}
[HttpPost]
public async Task<IActionResult> Create([FromBody] CreateProductCommand command)
{
var productId = await _mediator.SendAsync<CreateProductCommand, int>(command);
return Ok(new { ProductId = productId });
}
}
If your request does not return a value, just implement IRequest and call the simpler overload:
public record DeleteProductCommand(int ProductId) : IRequest;
await _mediator.SendAsync(deleteCommand);
Notifications (Events)
Sometimes one thing happening should trigger several independent reactions — for example, "a product was created" might need to update stock and send an email. This is what notifications are for.
Unlike a request, a notification can have zero, one, or many handlers, and every registered handler will be called.
// 1. Define the event
public record ProductCreatedEvent(int ProductId, string ProductName) : INotification;
// 2. Handler A – updates stock
public class NotifyStockSystemHandler : INotificationHandler<ProductCreatedEvent>
{
public async Task Handle(ProductCreatedEvent notification, CancellationToken cancellationToken)
{
// update stock system...
await Task.CompletedTask;
}
}
// 3. Handler B – sends an email
public class SendEmailToAdminHandler : INotificationHandler<ProductCreatedEvent>
{
public async Task Handle(ProductCreatedEvent notification, CancellationToken cancellationToken)
{
// send email...
await Task.CompletedTask;
}
}
// 4. Publish the event — both handlers above will run
await _mediator.PublishAsync(new ProductCreatedEvent(42, "Laptop"));
Pipeline Behaviors (Advanced)
A pipeline behavior lets you run code before and after a handler runs — without touching the handler itself. This is great for things like logging, validation, or timing.
public class DeleteProductIdValidationBehavior : IPipelineBehavior<DeleteProductCommand>
{
public async Task Handle(
DeleteProductCommand request,
RequestHandlerDelegate next,
CancellationToken cancellationToken)
{
if (request.ProductId <= 0)
throw new ArgumentException("Product Id must be greater than zero.");
// Call the next step in the pipeline (this eventually calls the handler)
await next();
}
}
Mediatron automatically discovers and registers any class that implements IPipelineBehavior<TRequest> or IPipelineBehavior<TRequest, TResponse> when you call AddMediatron.
Full Working Example
The repository includes a runnable console sample at sample/Mediatron.Sample that demonstrates:
- Registering Mediatron
- Sending a command that returns a value (
CreateProductCommand) - Publishing an event to multiple handlers (
ProductCreatedEvent) - Sending a command with no return value (
DeleteProductCommand) - A logging pipeline behavior
Run it with:
cd sample/Mediatron.Sample
dotnet run
Running the Tests
The test suite uses xUnit, FluentAssertions, and NSubstitute.
dotnet test
Project Structure
Mediatron/
├── src/Mediatron/ # The library itself
│ ├── Abstractions/ # Interfaces: IRequest, INotification, IPipelineBehavior, etc.
│ ├── Core/ # IMediator and its implementation (Mediator)
│ └── Extensions/ # AddMediatron() DI registration
├── sample/Mediatron.Sample/ # A runnable example console app
└── test/Mediatron.UnitTest/ # Unit tests
Documentation
For a deeper, guided walkthrough of every concept (requests, handlers, notifications, and pipeline behaviors), see the full documentation site built with DocFX in the documentation folder of this repository.
To build and view it locally:
dotnet tool install -g docfx
cd docfx
docfx docfx.json --serve
Then open your browser at http://localhost:8080.
Contributing
Contributions are welcome! Please see CONTRIBUTING.md and follow the Code of Conduct.
Security
If you discover a security issue, please read SECURITY.md for how to report it responsibly.
License
Mediatron is licensed under the MIT License.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Microsoft.Extensions.DependencyInjection (>= 10.0.11)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.1 | 102 | 8/24/2026 |
initial release