Commands
Commands represent imperative actions in your application. This guide covers everything you need to know about using commands effectively.
Overview
Commands are dispatched to all registered handlers sequentially in registration order. Use commands when you want to trigger side-effects across multiple consumers with no return value.
For the complete commands documentation, see the main README.
Basic Usage
await mediator.Send(new CreateUserCommand("john@example.com", "John Doe"));
Keyed Dispatch
Register handlers under routing keys and dispatch to a specific subset at runtime. This is useful for scenarios such as queue/topic routing, tenant isolation, or environment-specific handling:
// Registration — same message type, different keys
builder.Services.AddNetMediate(configure =>
{
configure.RegisterCommandHandler<DefaultHandler, MyCommand>(); // null key → "__default"
configure.RegisterCommandHandler<AuditHandler, MyCommand>("audit"); // keyed
});
// Dispatch to null-key (default) handlers
await mediator.Send(new MyCommand(), cancellationToken);
// Dispatch only to "audit" handlers
await mediator.Send("audit", new MyCommand(), cancellationToken);
The key is propagated through the entire pipeline — behaviors receive it in their Handle(object? key, ...) signature and can use it for routing, logging, or conditional logic.
Default routing key: A
nullkey is normalized internally to"__default". This meansmediator.Send(command, ct)andmediator.Send(null, command, ct)are exactly equivalent. Avoid using"__default"as your own routing key.
NativeAOT: Non-keyed registration and dispatch remain fully NativeAOT-compatible. Keyed registration uses
IKeyedServiceProviderinternally, which is not NativeAOT-compatible; use it only when NativeAOT is not required.