Registration and lifetimes
Dispatcher and handlers are scoped by default. Resolve them inside a DI scope, as ASP.NET Core does for each request.
Scanning an assembly
The usual setup registers infrastructure and then scans one or more assemblies:
builder.Services
.AddDispatcher()
.AddDispatcherHandlers(typeof(Program).Assembly);
AddDispatcher() registers infrastructure only and never scans assemblies implicitly.
AddDispatcherHandlers() registers internal handler classes. Registering the same assembly more than
once is safe.
Registering a single handler
A single handler can be registered explicitly instead of scanning for it:
using Dispatcher;
builder.Services.AddQueryHandler<GetGreetingQuery, string, GetGreetingQueryHandler>();
There is one method per handler kind: AddQueryHandler, AddCommandHandler, and
AddNotificationHandler.
Note
Registering handlers only through the typed methods means Dispatcher may not know about derived message types. See route targets.
Setting lifetimes
Each registration method takes an optional delegate that sets the handler lifetime, and assembly scanning takes the same delegate:
builder.Services.AddQueryHandler<GetGreetingQuery, string, GetGreetingQueryHandler>(options =>
options.ServiceLifetime = ServiceLifetime.Singleton);
builder.Services.AddDispatcherHandlers(
typeof(Program).Assembly,
options => options.ServiceLifetime = ServiceLifetime.Singleton);
The dispatcher itself is configured the same way, for applications that need a new instance for every resolution:
builder.Services.AddDispatcher(options =>
options.ServiceLifetime = ServiceLifetime.Transient);
Which lifetimes are accepted
Which lifetimes are accepted differs by what is being registered:
| Registered | Scoped |
Transient |
Singleton |
|---|---|---|---|
| Dispatcher | ✅ | ✅ | ❌ rejected |
| Handlers | ✅ | ✅ | ✅ |
Important
A singleton dispatcher is rejected because it would capture the root service provider and could not safely resolve scoped handlers or pipeline behaviors.
Pipeline behaviors are configured independently of both, through their own registration methods.
DispatcherOptions and DispatcherTelemetryOptions are in the Dispatcher namespace and ship in the
core Send0xx.Dispatcher package.