MeliorDispatch 1.0.1

dotnet add package MeliorDispatch --version 1.0.1
                    
NuGet\Install-Package MeliorDispatch -Version 1.0.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="MeliorDispatch" Version="1.0.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="MeliorDispatch" Version="1.0.1" />
                    
Directory.Packages.props
<PackageReference Include="MeliorDispatch" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add MeliorDispatch --version 1.0.1
                    
#r "nuget: MeliorDispatch, 1.0.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package MeliorDispatch@1.0.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=MeliorDispatch&version=1.0.1
                    
Install as a Cake Addin
#tool nuget:?package=MeliorDispatch&version=1.0.1
                    
Install as a Cake Tool

MeliorDispatch

A production-ready, high-performance mediator library for .NET 8/9/10 — a drop-in replacement for MediatR with Native AOT support, source-generated registration, and zero-reflection dispatch.

Status: Phases 1-11 complete (core abstractions, request/notification/stream dispatch, pipeline behaviors, dependency injection, source generator, Roslyn analyzers, benchmarks, samples, documentation). See the repository's phase plan for details.

Documentation

Packages

Everything ships in a single NuGet package, MeliorDispatch — install one package and you're done.

Internally it's built from two assemblies, mirroring MediatR's own split between its contracts and implementation:

  • MeliorDispatch.Abstractions — the public contract only: IRequest, INotification, handler interfaces, pipeline behavior interfaces, attributes. No implementation details.
  • MeliorDispatch — the mediator implementation and IServiceCollection registration extensions. Most of its types are internal, so they don't leak into consumers' IntelliSense or object browser.

The MeliorDispatch.Abstractions project is never packed or published on its own; its build output is merged into the MeliorDispatch package (lib/<tfm>/MeliorDispatch.Abstractions.dll alongside MeliorDispatch.dll), so there is exactly one package reference and no separate abstractions dependency to manage.

The Roslyn source generator (MeliorDispatch.SourceGenerator) and analyzers (MeliorDispatch.Analyzers) are delivered as build-time-only assets bundled inside this same package under analyzers/dotnet/cs/, so consuming projects only ever need <PackageReference Include="MeliorDispatch" /> - no separate package reference activates either one.

Source generator

Referencing MeliorDispatch automatically gets you the generator. It discovers request/notification/stream handlers declared in your project and emits, per assembly:

  • A [ModuleInitializer] that registers a compile-time-known dispatch wrapper per handler via MeliorDispatch.GeneratedHandlerRegistry, so dispatch for those request types needs no Type.MakeGenericType/reflection at runtime.
  • An AddGeneratedMediatorHandlers(IServiceCollection) extension method - call it alongside AddMediator() for handler registration with no assembly scanning: services.AddMediator().AddGeneratedMediatorHandlers();.

Analyzers

ID What it flags
MELIORDISP001 Duplicate handler for the same request type (reported by the source generator).
MELIORDISP002 A request/stream request has no handler anywhere in the compilation. Has a code fix that scaffolds a handler stub.
MELIORDISP003 A handler/behavior Sends the same request type it is handling, from inside its own Handle method (likely infinite recursion).
MELIORDISP004 A pipeline behavior/processor/exception handler-action never appears to be registered.
MELIORDISP005 Contradictory or unreachable IRequestHandler interface combination.
MELIORDISP006 A Singleton-lifetime handler declares a mutable instance field.
MELIORDISP007 A request type is never constructed anywhere in the compilation.
MELIORDISP008 A Handle method never references its CancellationToken parameter.

Benchmarks

src/MeliorDispatch.Benchmarks uses BenchmarkDotNet to compare MeliorDispatch against MediatR head-to-head on identically-shaped fixtures, measuring latency, allocations, and throughput via [MemoryDiagnoser]:

  • SendBenchmarks — single request/response dispatch against a pre-built service provider.
  • PublishBenchmarks — notification fan-out to three handlers (Sequential strategy on both sides).
  • StartupBenchmarks — the one-time cost of registering handlers and building the container, since that's a different cost profile than steady-state dispatch and shouldn't be conflated with it.

Run the full suite (this takes several minutes - BenchmarkDotNet does multiple warmup/measurement iterations per benchmark to get statistically sound numbers):

dotnet run -c Release --project src/MeliorDispatch.Benchmarks

Run a single class, or use BenchmarkDotNet's fast --job dry mode to sanity-check the harness itself without waiting for real measurements:

dotnet run -c Release --project src/MeliorDispatch.Benchmarks -- --filter "*SendBenchmarks*"

This project is intentionally the single consolidated benchmarks project; the original phase plan also mentions a tests/BenchmarkTests folder, which would just duplicate its job (BenchmarkDotNet benchmarks are the performance tests here), so a second copy was not created.

Samples

Five runnable samples under samples/, each demonstrating a different hosting model:

  • ConsoleSample — the smallest possible tour: Send, Publish to multiple handlers, CreateStream, and an open-generic logging IPipelineBehavior<,> registered via RegisterPipeline. Run with dotnet run --project samples/ConsoleSample.
  • WebApiSample — a controller-based ASP.NET Core API (a small Todo API) where the controller only calls ISender.Send; a CreateTodo command publishes a TodoCreated notification that a separate logging handler reacts to, so the write path and the logging concern stay decoupled. Run with dotnet run --project samples/WebApiSample and POST/GET /todos.
  • MinimalApiSample — minimal API endpoints calling ISender directly, including GET /weather/stream which returns sender.CreateStream(...) straight from the endpoint delegate - ASP.NET Core serializes the IAsyncEnumerable<T> as it's produced.
  • WorkerServiceSample — a BackgroundService on a PeriodicTimer. The important detail here is that the worker is a singleton but creates an IServiceScopeFactory scope per tick before resolving IMediator, exactly as an ASP.NET Core request scope would - a common source of subtle bugs if skipped.
  • AzureFunctionsSample — an isolated-worker Azure Function with an HTTP trigger, registering AddMediator the same way any other host does in Program.cs. Requires the Azure Functions Core Tools to run locally (func start from the project folder); its local.settings.json points at the storage emulator and contains no real secrets, so it's checked in as-is.

All five were built and actually run (not just compiled) as part of verifying this phase - including hitting the WebApiSample/MinimalApiSample/AzureFunctionsSample endpoints with curl and observing the WorkerServiceSample's log output tick.

License

MIT

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

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 140 7/28/2026
1.0.0 111 7/27/2026