Implement CQRS Design Pattern with MediatR in ASP.NET

Table of Contents

In this comprehensive guide, we'll delve into the powerful MediatR package and explore advanced features to elevate your .NET Core application. By the end of this article, you'll gain insights into:

  • Understanding CQRS: Unravel the concept of Command Query Responsibility Segregation (CQRS) and discover its significance in modern application architecture.
  • Seamless Integration of MediatR: Learn how to effortlessly integrate the MediatR package into your .NET Core application. Harness the potential of MediatR for effective command and query handling.
  • Configuring the MediatR Pipeline: Dive into the intricacies of configuring the MediatR pipeline in your .NET Core application. Unlock the full potential of MediatR by optimizing its pipeline to suit your application's specific needs.

What is MediatR library

The MediatR library works with two essential programming design patterns: CQRS and Mediator design.

What is Mediator Pattern?

According to Wikipedia, the mediator pattern is a behavioral pattern that defines an object that encapsulates how a set of objects interact. The mediator pattern reduces the dependencies between communicating objects, thereby reducing coupling.

What is Command Query Responsibility Segregation (CQRS)

The goal of CQRS is to standardize the separation of a model’s command and query. It recognizes that the requirements for reading and writing are very different and that supporting both in a single model may not be the best idea.

CQRS Diagram

  • The write model is used for processing commands (writes).
  • Multiple read models can be generated to handle queries, optimizing each read model based on its specific needs.

The MediatR library provides all the characteristics of the CQRS design, so let’s start implementing this in our .NET Core application.

How to implement MediatR in .NET Core application

Implementing MediatR in a .NET Core application is straightforward.

Install MediatR package from NuGet

Install the MediatR package from NuGet by running the following command in the terminal:

dotnet add package MediatR

Install MediatR Dependency Injection Package

dotnet add package Mediatr.Extensions.Microsoft.DependencyInjection

Register the mediator in the ConfigureServices method of the Startup class

services.AddMediatR(typeof(Startup));

Create Query

public class GetAllPosts : Audit, IRequest<List<Post>>
{
    // Additional properties and methods
}

Create Handler

public class GetAllPostsHandler : IRequestHandler<GetAllPosts, List<Post>>
{
    public Task<List<Post>> Handle(GetAllPosts request, CancellationToken cancellationToken)
    {
        var posts = new List<Post>()
        {
            new Post { Id = 1, Title = "Mediator" },
            new Post { Id = 2, Title = "Pipeline" }
        };
        return Task.FromResult(posts);
    }
}

Inject the IMediator in the control

[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
    private readonly IMediator _mediator;

    public ValuesController(IMediator mediator)
    {
        _mediator = mediator;
    }

    [HttpGet]
    public async Task<ActionResult<IEnumerable<Post>>> Get()
    {
        var allPosts = new GetAllPosts();
        var result = await _mediator.Send(allPosts);

        return Ok(new { Data = result, UpdatedDate = allPosts.UpdatedDate });
    }
}

MediatR Pipeline

If you want to add some pre and post-processing logic to your requests, you can use the MediatR pipeline behavior, which is similar to .NET Core middleware.

ClientMediatorHandlerMiddlewareSend RequestPre-processingHandle RequestReturn ResponsePost-processingReturn ResponseClientMediatorHandlerMiddleware

Consider the example where you want to add the UpdatedDate in every response. You can create a pipeline and then add it.

public class AuditPipeline<Tin, Tout> : IPipelineBehavior<Tin, Tout>
{
    private readonly HttpContext _httpContext;

    public AuditPipeline(IHttpContextAccessor httpContextAccessor)
    {
        _httpContext = httpContextAccessor.HttpContext;
    }

    public Task<Tout> Handle(Tin request, CancellationToken cancellationToken, RequestHandlerDelegate<Tout> next)
    {
        Console.WriteLine(request);

        if (request is Audit audit)
        {
            audit.UpdatedDate = DateTime.Now;
        }

        return next();
    }
}

Register the pipeline

In the ConfigureServices method of your Startup class, register the pipeline as shown below:

services.AddScoped(typeof(IPipelineBehavior<,>), typeof(AuditPipeline<,>));

This is open generic registration

In conclusion, this article has provided a comprehensive guide on implementing MediatR in your .NET Core application. By leveraging the power of MediatR and understanding the principles of CQRS, you can enhance the architecture and modularity of your application. Additionally, configuring the MediatR pipeline allows you to add custom logic and streamline the request handling process.

Post a Comment

Please do not post any spam link in the comment box😊

Previous Post Next Post

Blog ads

CodeGuru