Modern, extensible, and production-grade mediator engine for .NET 8+
With parallel notifications, streaming, pipelines, source generators, and full CQRS support via extensions.
Orchestrix.Mediator is a complete rethinking of a mediator engine for the modern .NET ecosystem.
✅ Reflection-based dispatch by default
🧬 Source generator dispatch (opt-in)
📢 Sequential & parallel notifications
📡 Streaming request handling (IAsyncEnumerable<T>)
🧱 Fully pluggable via pipelines and diagnostics hooks
🧩 CQRS-style ICommand, IQuery, and handler support (extension)
🔧 Minimal API & Controller friendly
🧪 Built for performance and testability
Full Documentation: Orchestrix.Mediator Docs →
dotnet add package Orchestrix.MediatorOptional Extensions
# Optional: Source generator-based dispatch
dotnet add package Orchestrix.Mediator.SourceGenerators
# Optional: CQRS abstractions (ICommand, IQuery, etc.)
dotnet add package Orchestrix.Mediator.Cqrs🧾 Define a request, notification, and handlers:
public record TestCommand(string? Name, string? Surname, string? Email, string? Phone) : IRequest<string>;
public class TestCommandHandler(IPublisher publisher) : IRequestHandler<TestCommand, string>
{
public async ValueTask<string> Handle(TestCommand request, CancellationToken cancellationToken)
{
Console.WriteLine($"Hello {request.Name} {request.Surname} {request.Email} {request.Phone}");
await publisher.Publish(new TestNotification(request.Name), cancellationToken);
return "OK";
}
}
public record TestNotification(string? Name) : INotification;
public class LogTestNotificationHandler : INotificationHandler<TestNotification>
{
public ValueTask Handle(TestNotification notification, CancellationToken cancellationToken)
{
Console.WriteLine($"[Generic Handler] Logging TestNotification: {notification.Name}");
return default;
}
}
public class ParallelTestNotificationHandler : IParallelNotificationHandler<TestNotification>
{
public async ValueTask Handle(TestNotification notification, CancellationToken cancellationToken)
{
Console.WriteLine($"[Parallel Handler] Simulating async work for {notification.Name}");
await Task.Delay(300, cancellationToken);
}
}[HttpGet]
public async Task<IActionResult> Test([FromServices] ISender sender)
{
var command = new TestCommand("Mohammad", "Anzawi", "[email protected]", "00000");
var result = await sender.Send(command, CancellationToken.None);
return Ok(result);
}Default (Reflection-based):
services.AddOrchestrix(cfg => cfg.RegisterHandlersFromAssemblies(typeof(SomeHandler).Assembly));Enable Source Generator (opt-in):
services.AddOrchestrix(cfg =>
{
cfg.UseSourceGenerator() // add this line
.RegisterHandlersFromAssemblies(typeof(SomeHandler).Assembly);
});| Mode | Description |
|---|---|
| 🪞 Reflection | Resolves via IServiceProvider |
| ⚡ Source Generator | Compile-time dispatch, AOT safe |
Source generators eliminate runtime lookup and boost performance.
See Source Generators →
| Interface | Role |
|---|---|
IRequest, IRequest<T> |
Request contracts |
INotification |
Fire-and-forget events |
ISender, IPublisher, IMediator |
Dispatch interfaces |
IRequestHandler<T>, IRequestHandler<T, R> |
Request handlers |
INotificationHandler<T>, IParallelNotificationHandler<T> |
Event handlers |
IStreamRequest<T>, IStreamRequestHandler<T, R> |
Async streaming support |
IPipelineBehavior<T, R> |
Pipeline behaviors |
VoidMarker (internal) |
Used internally to support IRequest (non-generic) in source-generated dispatch |
| Interface | Role |
|---|---|
ISendHook, IPublishHook, IStreamHook |
Lifecycle instrumentation |
IHookExecutor, HookConfiguration |
Hook orchestration & control |
Enable diagnostics, logging, tracing, or global behaviors with zero impact on business logic.
See Hooks & Pipelines →
Install:
dotnet add package Orchestrix.Mediator.CqrsAdds:
// Marker interfaces
ICommand, ICommand<TResponse>
IQuery<TResponse>
// Handlers
ICommandHandler<T>, ICommandHandler<T, R>
IQueryHandler<T, R>Supports both:
public class SaveCommand : ICommand; // No return
public class SaveCommand : ICommand<Unit>; // Explicit unitSee CQRS Guide →
Full Documentation: Orchestrix.Mediator Docs →
| Topic | Description |
|---|---|
| 🏁 Getting Started | Install, configure, send, publish |
| 🧠 Core Concepts | Interfaces, dispatcher roles |
| 🧭 CQRS Guide | ICommand, IQuery, etc. |
| ✨ Source Generators | Compile-time dispatching |
| 🪝 Hooks & Pipelines | Diagnostics + middleware |
| 📡 Streaming | Streaming requests |
| 📢 Notifications | Publish, parallelism |
| 🔍 Diagnostics | Tracing, hook config |
| 🌀 Sagas Guide | Add in-process Sagas |
| 🧙 Advanced Usage | TrySend, TryPublish, fallback |
| 📖 API Reference | Interface + type index |
| ❓ FAQ | Answers to common Qs |
| 🔁 Migration Guide | From MediatR to Orchestrix |
See MIGRATION.md
- Swap
IMediatortoISenderandIPublisher - Replace
IRequestHandler<>withICommandHandler<>/IQueryHandler<> - Replace
INotificationHandler<>withIParallelNotificationHandler<>if parallel behavior is needed - Enable
MediatorMode.SourceGeneratorfor performance - Use
Dispatch,DispatchVoid,TrySend,TryPublish, etc.
⚡ Zero-reflection dispatch via source generators
🧵 True parallel notifications
✅ ValueTask everywhere
🧬 NativeAOT-friendly
🔧 Small, fast, testable core
MIT — free for personal and commercial use.
Inspired by MediatR
Rebuilt from scratch for modern .NET by @anzawi
Proudly open-source and forever free
🦖 Orchestrix.Mediator: Mediation, Modernized.
