Mediator Pattern API Reference
Complete API documentation for the Mediator pattern in PatternKit.
Namespace
using PatternKit.Behavioral.Mediator;
Mediator
Allocation-light mediator supporting commands, notifications, and streaming.
public sealed class Mediator
Delegates
PreBehavior
public delegate ValueTask PreBehavior(in object? request, CancellationToken ct);
Invoked before handler execution. Can validate, log, or throw to short-circuit.
PostBehavior
public delegate ValueTask PostBehavior(in object? request, object? response, CancellationToken ct);
Invoked after handler (or stream) completion.
WholeBehavior
public delegate ValueTask<object?> WholeBehavior(in object? request, CancellationToken ct, MediatorNext next);
Wraps the handler for around advice (retry, timing, exception decoration).
MediatorNext
public delegate ValueTask<object?> MediatorNext(in object? request, CancellationToken ct);
Continuation delegate for whole behavior chains.
Methods
| Method | Returns | Description |
|---|---|---|
Send<TRequest, TResponse>(in TRequest, CancellationToken) |
ValueTask<TResponse?> |
Send command, receive response |
Publish<TNotification>(in TNotification, CancellationToken) |
ValueTask |
Publish to all notification handlers |
Stream<TRequest, TItem>(in TRequest, CancellationToken) |
IAsyncEnumerable<TItem> |
Stream items lazily |
Static Methods
| Method | Returns | Description |
|---|---|---|
Create() |
Builder |
Creates a new fluent builder |
Exceptions
| Method | Exception | Condition |
|---|---|---|
Send |
InvalidOperationException |
No handler registered for request type |
Send |
InvalidOperationException |
Response type mismatch |
Stream |
InvalidOperationException |
No stream handler registered |
Example
var mediator = Mediator.Create()
.Pre((in object req, CancellationToken _) =>
{
Console.WriteLine($"Processing: {req.GetType().Name}");
return default;
})
.Command<GetUser, User>((in GetUser q, CancellationToken ct) =>
new ValueTask<User>(userService.GetAsync(q.Id, ct)))
.Notification<UserCreated>((in UserCreated n, CancellationToken _) =>
{
SendEmail(n.UserId);
return default;
})
.Build();
var user = await mediator.Send<GetUser, User>(new GetUser(42));
await mediator.Publish(new UserCreated(42));
Mediator.Builder
Fluent builder for configuring the mediator.
public sealed class Builder
Typed Delegates
public delegate ValueTask<TResponse> CommandHandlerTyped<TRequest, TResponse>(in TRequest request, CancellationToken ct);
public delegate TResponse SyncCommandHandlerTyped<TRequest, out TResponse>(in TRequest request);
public delegate ValueTask NotificationHandlerTyped<TNotification>(in TNotification notification, CancellationToken ct);
public delegate void SyncNotificationHandlerTyped<TNotification>(in TNotification notification);
public delegate IAsyncEnumerable<TItem> StreamHandlerTyped<TRequest, out TItem>(in TRequest request, CancellationToken ct);
Methods
| Method | Returns | Description |
|---|---|---|
Pre(PreBehavior) |
Builder |
Add pre behavior (before handler) |
Post(PostBehavior) |
Builder |
Add post behavior (after handler) |
Whole(WholeBehavior) |
Builder |
Add whole behavior (wraps handler) |
Command<TReq, TRes>(CommandHandlerTyped) |
Builder |
Register async command handler |
Command<TReq, TRes>(SyncCommandHandlerTyped) |
Builder |
Register sync command handler |
Notification<T>(NotificationHandlerTyped) |
Builder |
Register async notification handler |
Notification<T>(SyncNotificationHandlerTyped) |
Builder |
Register sync notification handler |
Stream<TReq, TItem>(StreamHandlerTyped) |
Builder |
Register streaming handler |
Build() |
Mediator |
Build immutable mediator |
Behavior Execution Order
sequenceDiagram
participant Client
participant Pre as Pre Behaviors
participant Whole as Whole Behaviors
participant Handler
participant Post as Post Behaviors
Client->>Pre: Execute in registration order
Pre->>Whole: First wraps last (onion)
Whole->>Handler: Innermost calls handler
Handler-->>Whole: Response
Whole-->>Post: Execute in registration order
Post-->>Client: Final response
Example
var mediator = Mediator.Create()
// Behaviors
.Pre((in object req, CancellationToken ct) =>
{
Log.Info($"Pre: {req.GetType().Name}");
return default;
})
.Whole((in object req, CancellationToken ct, Mediator.MediatorNext next) =>
{
var sw = Stopwatch.StartNew();
var result = await next(in req, ct);
Log.Info($"Elapsed: {sw.ElapsedMilliseconds}ms");
return result;
})
.Post((in object req, object? res, CancellationToken ct) =>
{
Log.Info($"Post: {res}");
return default;
})
// Commands
.Command<CreateOrder, Order>((in CreateOrder cmd, CancellationToken ct) =>
orderService.CreateAsync(cmd, ct))
// Notifications (multiple handlers allowed)
.Notification<OrderCreated>((in OrderCreated n, CancellationToken _) =>
{
emailService.SendConfirmation(n.OrderId);
return default;
})
.Notification<OrderCreated>((in OrderCreated n, CancellationToken _) =>
{
analyticsService.Track(n.OrderId);
return default;
})
// Streaming
.Stream<GetOrders, Order>((in GetOrders q, CancellationToken ct) =>
orderService.GetAllAsync(q.UserId, ct))
.Build();
Message Types Comparison
| Feature | Command | Notification | Stream |
|---|---|---|---|
| Handlers | Single | Multiple | Single |
| Response | Yes | No | Async sequence |
| Pre behaviors | Yes | Yes | Yes |
| Whole behaviors | Yes | No | Yes |
| Post behaviors | Yes | Yes | Yes (after completion) |
| Missing handler | Throws | No-op | Throws |
Thread Safety
| Component | Thread-Safe |
|---|---|
Builder |
No - use from single thread |
Mediator |
Yes - immutable after build |
Send |
Yes - concurrent calls safe |
Publish |
Yes - concurrent calls safe |
Stream |
Yes - concurrent calls safe |
Implementation Notes
- Handlers stored in
ReadOnlyDictionaryfor immutability ValueTaskeverywhere for allocation-light async- Typed handlers adapted to boxed signatures at build time
- Pre behaviors execute in registration order
- Whole behaviors wrap inside-out (last registered is innermost)
- Post behaviors execute in registration order
Platform Support
| Feature | .NET Standard 2.0 | .NET Standard 2.1+ |
|---|---|---|
| Commands | Yes | Yes |
| Notifications | Yes | Yes |
| Streaming | No | Yes |