Roadmap
This roadmap consolidates improvement ideas and new features for the NetMediate ecosystem.
Completed
- Source generator support (
NetMediate.SourceGeneration) — generates a GenDI-firstAddNetMediate()entrypoint plus typed dispatch extensions and framework behavior wrappers at compile time. - Benchmark suite with load and pipeline-variant tests covering commands, requests, notifications, and streams.
- NativeAOT and trimming compatibility — no
MakeGenericType, no assembly scanning, notypeof(TResult)runtime switches; the compile-time path stays on generated entrypoints, typed dispatch, and closed-type DI resolution. - Notification adapter contracts and utilities can be implemented as user-defined pipeline behaviors that forward notifications to external queues and streams.
-
NetMediate.Moqhelper package with fluent async setup extensions and mediator mock registration. - Marker-interface-free messaging — any plain class or record can be a message type.
-
Task-based handler contracts — all handlerHandlemethods returnTaskorTask<TResponse>. - Sample applications (API, Worker, Minimal API) in
docs/SAMPLES.md. - Full documentation suite: installation, configuration, source generation, AOT, Moq recipes, benchmarks.
Near term
- Coverage gate — enforce 100 % line coverage for
src/NetMediatein CI so no internal path goes untested. - BenchmarkDotNet suite — dedicated
NetMediate.Benchmarksconsole project withCoreDispatchBenchmarkscovering command, notification, request, and stream;[MemoryDiagnoser]reports mean, alloc/op, gen0; supports both JIT and NativeAOT runs via-p:AotBenchmark=true. - Per-commit throughput regression gate — fail CI if the
commandscenario drops more than 5 % from the previous commit baseline.
Medium term
- Synchronous fire-and-forget notifier — optional
INotifiableimplementation that dispatches notification handlers inline with no extra transport layer for scenarios where latency matters more than isolation. - Pre-compiled behavior chain — build the behavior delegate chain once at startup per message type and cache it in a static generic field, eliminating the per-call
Reverse/Aggregate/closure allocation. - Single-handler fast path for
Send— when exactly oneICommandHandler<T>is registered, invoke it directly without theforeachloop. - Structured error context — surface handler exceptions through a typed
MediatorExceptioncarrying the originating message type, handler type, and activity trace ID.
Long term
- Streaming fan-out — multiple
IStreamHandler<TMsg, TResp>registrations are supported; their items are merged sequentially into a singleIAsyncEnumerable<TResp>, analogous to howSendfans out to multiple command handlers. - Keyed handler registration — runtime routing via service keys. Handlers can be annotated with GenDI metadata such as
[Injectable(..., Key = "routingKey")]and dispatched withSend(key, message),Request(key, ...),Notify(key, ...), orRequestStream(key, ...). Non-keyed registration and dispatch (usingnullkey) continues to work as before.