ZeroAlloc.Mediator.Generator
6.6.3
dotnet add package ZeroAlloc.Mediator.Generator --version 6.6.3
NuGet\Install-Package ZeroAlloc.Mediator.Generator -Version 6.6.3
<PackageReference Include="ZeroAlloc.Mediator.Generator" Version="6.6.3"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference>
<PackageVersion Include="ZeroAlloc.Mediator.Generator" Version="6.6.3" />
<PackageReference Include="ZeroAlloc.Mediator.Generator"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference>
paket add ZeroAlloc.Mediator.Generator --version 6.6.3
#r "nuget: ZeroAlloc.Mediator.Generator, 6.6.3"
#:package ZeroAlloc.Mediator.Generator@6.6.3
#addin nuget:?package=ZeroAlloc.Mediator.Generator&version=6.6.3
#tool nuget:?package=ZeroAlloc.Mediator.Generator&version=6.6.3
ZeroAlloc.Mediator
A source-generated MediatR alternative for .NET 8 and .NET 10: requests, notifications and streams dispatched without reflection, with no allocations on the Send and Publish hot path, ready for NativeAOT.
Why ZeroAlloc.Mediator
- 0 B per
SendandPublish. The staticMediatorpath, pipeline behaviors included, is held at zero bytes byAllocationGatetests. MediatR allocates 224 B perSendand 792 B per single-handlerPublishin the same benchmark. - 3.9–20x faster than MediatR on
SendandPublishin the same BenchmarkDotNet run. ThroughIMediatorresolved from a new scope per call, the way an ASP.NET Core request does, it is still 1.4–3.2x faster and allocates 176–200 B against MediatR's 352–1,232 B. - Works under NativeAOT and trimming. Dispatch is a generated, strongly-typed overload per request type: no reflection, no dictionary lookup, no handler scanning at startup. CI publishes and runs a NativeAOT sample on every build.
- Mistakes fail the build, not the request. A request with no handler, two handlers for one request or a misconfigured behavior is reported by the generator as a compiler diagnostic.
Install
dotnet add package ZeroAlloc.Mediator
dotnet add package ZeroAlloc.Mediator.Generator
The second package is the source generator; it is added as a private development dependency. See Getting Started for multi-project solutions.
Quick start
using ZeroAlloc.Mediator;
decimal total = await Mediator.Send(new AddToCart(Quantity: 3, UnitPrice: 9.99m));
Console.WriteLine(total); // 29.97
public readonly record struct AddToCart(int Quantity, decimal UnitPrice) : IRequest<decimal>;
public sealed class AddToCartHandler : IRequestHandler<AddToCart, decimal>
{
public ValueTask<decimal> Handle(AddToCart request, CancellationToken ct)
=> ValueTask.FromResult(request.Quantity * request.UnitPrice);
}
Mediator.Send(AddToCart) is an overload the generator wrote for this request, so the call is checked by the compiler and dispatches straight to the handler. In an ASP.NET Core app, call builder.Services.AddMediator() and inject IMediator; see Dependency Injection.
What you get
- Requests and responses: commands and queries with a typed response, or
Unitfor none. - Notifications: publish to every handler, sequentially or in parallel with
[ParallelNotification], and handlers for a base interface receive derived notifications too. - Streaming:
IAsyncEnumerable<T>results throughCreateStream. - Pipeline behaviors: logging, validation, transactions and other cross-cutting code, inlined into each dispatch at compile time instead of iterated from a list.
- Dependency injection: a generated
AddMediator()andIMediator, with handler lifetimes you choose. - Analyzer diagnostics: ZAM001–ZAM011, with fixes, in the diagnostics reference.
Optional packages plug into the pipeline; reference one and call its With...() method on AddMediator():
ZeroAlloc.Mediator.Validation: runs the ZeroAlloc.Validation validator for a request before its handler.WithValidation()ZeroAlloc.Mediator.Authorization: gates dispatch on[RequirePolicy]checks from ZeroAlloc.Authorization.WithAuthorization()ZeroAlloc.Mediator.Cache: caches responses for requests marked[CacheResponse].WithCache()ZeroAlloc.Mediator.Resilience: retry, timeout and circuit-breaker policies through ZeroAlloc.Resilience.WithResilience()ZeroAlloc.Mediator.Telemetry: OpenTelemetry request count and duration metrics.WithTelemetry()
Performance
.NET 10, BenchmarkDotNet, ZeroAlloc.Mediator and MediatR in the same run. Allocations are exact; speed is a same-run ratio.
| Operation | Speed vs MediatR | ZeroAlloc.Mediator | MediatR |
|---|---|---|---|
Send, static Mediator |
3.9x faster | 0 B | 224 B |
Publish, 1 handler, static Mediator |
16x faster | 0 B | 792 B |
Send via IMediator, new DI scope per call |
1.5x faster | 176 B | 496 B |
The 176 B is the DI scope and the transient IMediator, not the dispatch. The static rows hold with no factory registered, for a handler without instance state. The performance page has every row, including pipelines and streaming, and explains where each byte comes from.
Learn more
- Documentation: mediator.zeroalloc.net, or the docs folder on GitHub, including migration guides.
- Related ZeroAlloc packages:
- ZeroAlloc.Pipeline (docs): Mediator's pipeline behaviors are ZeroAlloc.Pipeline behaviors, and its generator inlines them.
- ZeroAlloc.Validation (docs): source-generated validators that
ZeroAlloc.Mediator.Validationruns before each handler. - ZeroAlloc.Authorization (docs): the policies that
ZeroAlloc.Mediator.Authorizationchecks before dispatch. - ZeroAlloc.Results (docs): give a request a
Resultresponse and the validation and authorization packages return failures in it instead of throwing.
- Contributing: issues and pull requests are welcome on GitHub.
- License: MIT, see LICENSE.
Learn more about Target Frameworks and .NET Standard.
This package has no dependencies.
NuGet packages (8)
Showing the top 5 NuGet packages that depend on ZeroAlloc.Mediator.Generator:
| Package | Downloads |
|---|---|
|
ZeroAlloc.Saga
Source-generated long-running process orchestration. Multi-step sagas with compensation, FSM via ZeroAlloc.StateMachine, dispatch via ZeroAlloc.Mediator. Native AOT compatible. |
|
|
ZeroAlloc.Saga.Outbox
Transactional outbox bridge for ZeroAlloc.Saga — command dispatch committed atomically with the saga state save on EF Core, on Redis with ZeroAlloc.Saga.Outbox.Redis, and on ZeroAlloc.ORM with ZeroAlloc.Saga.Outbox.Orm. |
|
|
ZeroAlloc.Saga.EfCore
Entity Framework Core durable persistence backend for ZeroAlloc.Saga. Single shared SagaInstance table, row-version OCC, retry-on-conflict. Native AOT compatible. |
|
|
ZeroAlloc.Saga.Redis
Redis-backed durable persistence for ZeroAlloc.Saga. WATCH/MULTI/EXEC-based optimistic concurrency, hash-per-saga storage, byte-encoded state via ISagaPersistableState. Native AOT compatible. |
|
|
ZeroAlloc.Saga.Resilience
Resilience bridge for ZeroAlloc.Saga — wraps step-command dispatch in retry / timeout / circuit-breaker / rate-limit policies from ZeroAlloc.Resilience. Native AOT compatible. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 6.6.3 | 231 | 10/18/2026 |
| 6.6.2 | 1,230 | 10/16/2026 |
| 6.6.1 | 632 | 10/15/2026 |
| 6.6.0 | 679 | 10/12/2026 |
| 6.5.0 | 579 | 10/11/2026 |
| 6.4.3 | 204 | 10/11/2026 |
| 6.4.2 | 572 | 10/11/2026 |
| 6.4.1 | 94 | 10/11/2026 |
| 6.4.0 | 163 | 10/10/2026 |
| 6.3.0 | 242 | 10/10/2026 |
| 6.2.0 | 169 | 10/9/2026 |
| 6.1.1 | 556 | 10/2/2026 |
| 6.1.0 | 255 | 9/30/2026 |
| 6.0.3 | 530 | 9/30/2026 |
| 6.0.2 | 256 | 9/28/2026 |
| 6.0.1 | 109 | 9/28/2026 |
| 6.0.0 | 1,150 | 9/27/2026 |
| 5.1.5 | 5,566 | 9/21/2026 |
| 5.1.4 | 350 | 9/20/2026 |
| 5.1.3 | 126 | 9/20/2026 |