NEWAI for .NET Developers - skills, agents and practical lessonsExplore

MediatR Pipeline Behavior

Stefan ĐokićJan 1, 20243 min read.NET

Sponsored

Many thanks to the sponsors who make it possible for this newsletter to be free for readers.

Want to reach thousands of .NET developers? Sponsor TheCodeMan →

Watch MediatR Pipeline Behavior on YouTube

Watch MediatR Pipeline Behavior on YouTube

The Background

MediatR is a popular library in .NET used for implementing the Mediator pattern. It helps in reducing coupling between components and makes it easier to manage code by sending requests to the appropriate handlers. A Pipeline Behavior in MediatR is a concept that allows developers to implement cross-cutting concerns (like logging, validation, etc.) for MediatR requests. How to implement it? Let's take a look deeply!

Define a Pipeline Behavior Interface

This interface represents a pipeline behavior that will be applied to every request and its corresponding response. MediatR provides an interface called IPipelineBehavior<TRequest, TResponse> that you can implement.

C#
public interface IPipelineBehavior<TRequest, TResponse>{    Task<TResponse> Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate<TResponse> next);}

Implement the Pipeline Behavior

You create a class that implements the IPipelineBehavior<TRequest, TResponse> interface . This class will contain the logic that you want to apply to requests. For example, a simple logging behavior:

C#
public class LoggingBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse>{    private readonly ILogger<LoggingBehavior<TRequest, TResponse>> _logger;     public LoggingBehavior(ILogger<LoggingBehavior<TRequest, TResponse>> logger)    {        _logger = logger;    }     public async Task<TResponse> Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate<TResponse> next)    {        // Pre-processing        _logger.LogInformation($"Handling {typeof(TRequest).Name}");         var response = await next();         // Post-processing        _logger.LogInformation($"Handled {typeof(TResponse).Name}");         return response;    }}

The LoggingBehavior<TRequest, TResponse> in a MediatR pipeline will automatically log information both before and after each request is processed. When a request is made, it logs the type of request being handled, then passes control to the next handler in the pipeline. After the request is handled, it logs the type of response generated, providing an audit trail of the requests and responses within the application.

Register the Pipeline Behavior

In the startup configuration of your application, register your pipeline behavior so that MediatR knows to apply it to requests.

C#
services.AddTransient(typeof(IPipelineBehavior<, ), typeof(LoggingBehavior<, )));

With this setup, every time a MediatR request is made, it will go through this LoggingBehavior (or any other behavior you define) before reaching the actual request handler. This allows you to add additional processing like logging, validation, or even exception handling in a clean, reusable way.

How and when is it used?

Let's say we have a basic MediatR request defined:

C#
public class MyRequest : IRequest<MyResponse>{    // Request properties} public class MyRequestHandler : IRequestHandler<MyRequest, MyResponse>{    public async Task<MyResponse> Handle(MyRequest request, CancellationToken cancellationToken)    {        // Handle the request        return new MyResponse();    }}

When you call _mediator.Send(new MyRequest()) , MediatR will process this request through the pipeline behavior (e.g., LoggingBehavior) before it reaches MyRequestHandler. This allows you to add common logic, like logging, validation, or error handling, in a centralized way without cluttering the business logic in the handlers.

Wrapping up

The LoggingBehavior<TRequest, TResponse> in MediatR for .NET enhances application monitoring and debugging by consistently logging all request and response types. This approach promotes cleaner code through separation of concerns, adheres to best practices like the Single Responsibility Principle, and offers ease of integration and reusability across the application.

If you want to implement CQRS with or without MediatR, check out How to implement CQRS without MediatR. For a fully custom pipeline without any external dependencies, see Build Your Own MediatR: A Lightweight Handler Pipeline.

Frequently Asked Questions

What is MediatR Pipeline Behavior?

MediatR Pipeline Behavior is a feature that lets you add cross-cutting concerns (logging, validation, caching, error handling) to your request pipeline without modifying individual handlers. You implement IPipelineBehavior<TRequest, TResponse> and register it in DI. Every request that passes through MediatR will execute your behavior before and after the handler.

How do I register a Pipeline Behavior in .NET?

Register your pipeline behavior as an open generic in your DI container: services.AddTransient(typeof(IPipelineBehavior<,>), typeof(LoggingBehavior<,>)). MediatR will automatically discover and execute it for every request/response pair. You can register multiple behaviors — they execute in the order they are registered.

Can I have multiple Pipeline Behaviors?

Yes. You can chain multiple behaviors like logging, validation, and caching. Each behavior calls next() to pass execution to the next behavior or the final handler. The execution order matches the registration order in your DI container.

That's all from me today - first day of the year. See ya on the next Monday coffee. P.S. Follow me on YouTube.


Want more design patterns with real-world examples? My ebook Design Patterns that Deliver covers 5 essential patterns (Builder, Decorator, Strategy, Adapter, Mediator) with hands-on C# code you can use right away. Or try a free chapter on the Builder Pattern first.

Stefan Đokić
About the author

Stefan Đokić

Microsoft MVP and senior .NET engineer with extensive experience designing enterprise-grade systems and teaching architectural best practices.

Every Monday · Free

One practical .NET & architecture tip, every Monday.

Join 25,000+ engineers who improve their C# skills in a 5-minute read.

No spam. Unsubscribe anytime.