Class ValidationBehavior<TMessage, TResponse>
Unified validation stage of the Trellis Mediator pipeline. Runs the compile-time
IValidate contract (when the message implements it) and every
IMessageValidator<TMessage> registered for TMessage
in DI, aggregates all Error.UnprocessableContent failures into a single
response failure, and short-circuits the pipeline before the handler is invoked.
public sealed class ValidationBehavior<TMessage, TResponse> : IPipelineBehavior<TMessage, TResponse> where TMessage : IMessage where TResponse : IResult, IFailureFactory<TResponse>
Type Parameters
TMessageThe message type.
TResponseThe response type, constrained to IResult and IFailureFactory<TSelf> so the behavior can construct typed failures without reflection.
- Inheritance
-
ValidationBehavior<TMessage, TResponse>
- Implements
-
IPipelineBehavior<TMessage, TResponse>
- Inherited Members
- Extension Methods
Remarks
The behavior runs for every message — including messages that do not implement IValidate and have no registered IMessageValidator<TMessage> — in which case it is a no-op pass-through with one DI resolve and one type test.
Failure aggregation rules:
- Multiple Error.UnprocessableContent failures (from IValidate and any number of IMessageValidator<TMessage> instances) are merged into a single Error.UnprocessableContent whose Fields contains every reported FieldViolation and whose Rules contains every reported RuleViolation.
- An Error.UnprocessableContent with empty Fields AND empty Rules still short-circuits the handler: the original failure semantics from the validator are preserved, even when no violations are reported.
- A non-Error.UnprocessableContent failure (e.g., Error.Conflict, Error.Forbidden) returned by any validation source short-circuits the stage immediately and that failure is propagated as-is, with no further validators consulted.
Constructors
ValidationBehavior(IEnumerable<IMessageValidator<TMessage>>)
Unified validation stage of the Trellis Mediator pipeline. Runs the compile-time
IValidate contract (when the message implements it) and every
IMessageValidator<TMessage> registered for TMessage
in DI, aggregates all Error.UnprocessableContent failures into a single
response failure, and short-circuits the pipeline before the handler is invoked.
public ValidationBehavior(IEnumerable<IMessageValidator<TMessage>> validators)
Parameters
validatorsIEnumerable<IMessageValidator<TMessage>>
Remarks
The behavior runs for every message — including messages that do not implement IValidate and have no registered IMessageValidator<TMessage> — in which case it is a no-op pass-through with one DI resolve and one type test.
Failure aggregation rules:
- Multiple Error.UnprocessableContent failures (from IValidate and any number of IMessageValidator<TMessage> instances) are merged into a single Error.UnprocessableContent whose Fields contains every reported FieldViolation and whose Rules contains every reported RuleViolation.
- An Error.UnprocessableContent with empty Fields AND empty Rules still short-circuits the handler: the original failure semantics from the validator are preserved, even when no violations are reported.
- A non-Error.UnprocessableContent failure (e.g., Error.Conflict, Error.Forbidden) returned by any validation source short-circuits the stage immediately and that failure is propagated as-is, with no further validators consulted.
Methods
Handle(TMessage, MessageHandlerDelegate<TMessage, TResponse>, CancellationToken)
public ValueTask<TResponse> Handle(TMessage message, MessageHandlerDelegate<TMessage, TResponse> next, CancellationToken cancellationToken)
Parameters
messageTMessagenextMessageHandlerDelegate<TMessage, TResponse>cancellationTokenCancellationToken
Returns
- ValueTask<TResponse>