IDispatcher
Namespace: RA.Utilities.Dispatcher.Abstractions
The IDispatcher interface is the central abstraction for dispatching requests and publishing notifications within your CQRS (Command Query Responsibility Segregation) architecture.
It serves as the primary entry point for triggering business logic from your presentation layer (e.g., an API endpoint).
The implementation is source-generated — the package's generator emits the Mediator class into your assembly, and AddMediator() registers it as the IDispatcher implementation. See Generated Mediator for the dispatch strategy.
🎯 Purpose and Function
The IDispatcher interface elegantly decouples the sender of a message from its handler.
An endpoint doesn't need to know which class handles creating a product;
it simply creates a CreateProductCommand and asks the dispatcher to send it.
The dispatcher then takes responsibility for finding and invoking the correct handler.
This interface combines two fundamental communication patterns:
- Request/Response (
Sendmethods): This is used for commands (actions that change state) and queries (requests for data). It's a one-to-one pattern where a singleIRequestis dispatched to a singleIRequestHandler.
Send<TRequest>(...): For requests that do not return a value — returnsValueTask<Result>.Send<TRequest, TResponse>(...): For requests that return a value — returnsValueTask<Result<TResponse>>.
Dispatch is Result-based: expected failures are returned as Result.Failure(exception) instead of being thrown. Context overloads (Send<TRequest, TResponse, TContext> and Send<TRequest, TContext>) add an optional PipelineContext<TContext>? context parameter.
- Publish/Subscribe (
Publishmethod): This is used for events or notifications (INotification). It's a one-to-many pattern where a single notification is published to all registeredINotificationHandlers(zero, one, or many). This is perfect for handling side effects like clearing a cache or sending an email after an operation completes.Publishruns every handler and aggregates failures into the returnedValueTask<Result>.
🚀 Usage Example
using RA.Utilities.Core.Results;
using RA.Utilities.Dispatcher.Abstractions;
app.MapPost("todos", static async (
[FromServices] IDispatcher dispatcher,
CancellationToken cancellationToken
) =>
{
Result sendResult = await dispatcher.Send(new CreateUserCommand("Alice"), cancellationToken);
if (sendResult.IsFailure)
return Results.BadRequest(sendResult.Exception.Message);
Result publishResult = await dispatcher.Publish(new UserCreatedEvent(Guid.NewGuid()), cancellationToken);
return publishResult.IsSuccess ? Results.Ok() : Results.Accepted();
})