MediatR Pipeline Behavior

Jan 1 2024

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

 

• If you have ever used Postman to debug and write tests for your REST APIs, guess what, those are the same concepts you need to know for writing tests for your gRPC requests in Postman
For more info about gRPC, they created a great beginner article here .

 
 

The Background

 
 

 

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.

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:

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.

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:

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.

 

That's all from me today - first day of the year.

 

See ya on the next Monday coffee.

 

Join 10,950+ subscribers to improve your .NET Knowledge.

There are 3 ways I can help you:

Design Patterns Simplified ebook

Go-to resource for understanding the core concepts of design patterns without the overwhelming complexity. In this concise and affordable ebook, I've distilled the essence of design patterns into an easy-to-digest format. It is a Beginner level. Check out it here.


Sponsorship

Promote yourself to 10,950+ subscribers by sponsoring this newsletter.


Join .NET Pro Weekly Newsletter

Every Monday morning, I share 1 actionable tip on C#, .NET & Arcitecture topic, that you can use right away.


Subscribe to
.NET Pro Weekly

Subscribe to the .NET Pro Weekly and be among the 10,950+ subscribers gaining practical tips and resources to enhance your .NET expertise.