The TaskHub.Shared command pipeline defines three distinct stages for behaviors. Understanding the lifecycle is crucial for implementing cross-cutting concerns correctly.
Pre-behaviors are executed before the handler. They follow the classic middleware pattern.
public interface IPreBehavior<TCommand, TResult>
where TCommand : ICommand
where TResult : Result
{
Task<TResult> HandleAsync(
TCommand command,
Func<TCommand, CancellationToken, Task<TResult>> next,
CancellationToken ct);
}
Post-transformers are executed after the handler and all pre-behaviors have completed, but before the result is returned to the caller.
public interface IPostTransformer<TCommand, TResult>
where TCommand : ICommand
where TResult : Result
{
Task<TResult> HandleAsync(
TCommand command,
TResult current,
Func<TCommand, TResult, CancellationToken, Task<TResult>> next,
CancellationToken ct);
}
Post-behaviors are executed after the final result has been determined (including transformations). They are intended for side-effects.
public interface IPostBehavior<in TCommand, in TResult>
where TCommand : ICommand
where TResult : Result
{
Task<Result> HandleAsync(TCommand command, TResult result, CancellationToken ct);
}
| Stage | Can Short-circuit? | Can Modify Result? | Execution Order |
|---|---|---|---|
| Pre | Yes | Yes (by returning own result) | Outer to Inner (Low Order to High) |
| Trans | No (next is mandatory) | Yes | Inner to Outer (Low Order to High) |
| Post | No | No | Sequential (Low Order to High) |