AddMediator(configure) (v1.2.0+)The simplest way to register the mediator is the single-call AddMediator(configure) overload. It handles the entire registration sequence automatically:
services.AddMediator(builder =>
{
builder.AddOpenBehavior(typeof(LoggingBehavior<,>));
builder.AddRequestPreProcessor<ValidationPreProcessor>();
builder.AddRequestPostProcessor<AuditPostProcessor>();
builder.AddRequestExceptionHandler<GlobalExceptionHandler>();
builder.AddParallelNotificationPublisher();
});
Internally, this single call executes in order:
AddMediator() — registers core services (IMediator, ISender, IPublisher)RegisterMediatorHandlers() — discovers and registers all handlersconfigure(builder) — your pipeline customizationPrecompilePipelines() + Freeze() — precompiles dispatch tablesDo not mix
AddMediator(configure)with individual registration calls. CallingRegisterMediatorHandlers()orPrecompilePipelines()separately alongsideAddMediator(configure)causes redundant registrations. The compile-time diagnostic DSOFT007 will warn you if mixed usage is detected. Runtime idempotency guards prevent actual double-registration, but the intent should be clear in your code.
If you need fine-grained control over the registration order, use the individual methods.
The Precompile* methods inspect the IServiceCollection at startup to determine dispatch strategies and chain lifetimes. All service registrations must happen before the corresponding Precompile* call.
services
.AddMediator() // 1. Core mediator services
.RegisterMediatorHandlers(); // 2. Source-generated handler registrations
// 3. Register behaviors, processors, exception handlers
services.AddTransient(typeof(IPipelineBehavior<,>), typeof(LoggingBehavior<,>));
services.AddTransient(typeof(IRequestPreProcessor<>), typeof(ValidationPreProcessor<>));
services.AddTransient(typeof(IRequestPostProcessor<,>), typeof(AuditPostProcessor<,>));
// 4. Override handler lifetimes (optional)
services.AddScoped<IRequestHandler<MyRequest, MyResponse>, MyHandler>();
// 5. Register notification strategies (optional)
services.AddSingleton<INotificationPublisher, ParallelNotificationPublisher>();
// 6. Precompile — inspects all registrations above
services
.PrecompilePipelines() // scans for IPipelineBehavior, Pre/Post processors, exception handlers
.PrecompileNotifications() // builds static dispatch arrays for each INotification type
.PrecompileStreams(); // builds static factory delegates for each IStreamRequest type
| Method | What it inspects | What to register before |
|---|---|---|
PrecompilePipelines() |
IPipelineBehavior<,>, IRequestPreProcessor<>, IRequestPostProcessor<,>, IRequestExceptionHandler<,>, handler lifetimes |
Behaviors, processors, exception handlers, handler overrides |
PrecompileNotifications() |
INotificationHandler<> |
Notification handler overrides |
PrecompileStreams() |
IStreamRequestHandler<,> |
Stream handler overrides |
PrecompilePipelines() determines each PipelineChainHandler lifetime based on the registered components: Singleton when all components are Singleton, Scoped when any is Scoped, Transient when any is Transient. Registrations added after the Precompile* calls will not be picked up by the dispatch tables.