DSoftStudio Mediator

← Back to Documentation

Pre/Post Processors

For cross-cutting concerns that only need a “before” or “after” hook, pre/post processors are simpler than full pipeline behaviors — no next parameter, no chain responsibility.

PreProcessor₁ → PreProcessor₂ → Handler → PostProcessor₁ → PostProcessor₂

Pre-Processors

Run before the handler. If a pre-processor throws, the handler is not invoked.

public class ValidationPreProcessor<TRequest> : IRequestPreProcessor<TRequest>
{
    public ValueTask Process(TRequest request, CancellationToken ct)
    {
        // Validate before the handler runs — throw to short-circuit
        if (request is ICommand command)
            Console.WriteLine($"Validating {typeof(TRequest).Name}");

        return ValueTask.CompletedTask;
    }
}

Post-Processors

Run after the handler completes successfully. Not invoked if the handler throws.

public class AuditPostProcessor<TRequest, TResponse>
    : IRequestPostProcessor<TRequest, TResponse>
{
    public ValueTask Process(TRequest request, TResponse response, CancellationToken ct)
    {
        Console.WriteLine($"{typeof(TRequest).Name}{response}");
        return ValueTask.CompletedTask;
    }
}

Registration

Register as open generics:

services.AddTransient(typeof(IRequestPreProcessor<>), typeof(ValidationPreProcessor<>));
services.AddTransient(typeof(IRequestPostProcessor<,>), typeof(AuditPostProcessor<,>));