MediatR and CQRS Pattern | Software Architecture 101

The goal of this blog post is simple..

First, we talk about CQRS software pattern and its use cases… why it is so damn important to have a decoupled application achieved by the CQRS Pattern.Then we’ll dive into what MediatR is and what it can do…

CQRS Pattern

This image below explains about two models within the Application layer, which is the Query and Command model.

The Front-End UI communicates with these models to create, update, safe and receive data from the Database.


Why CQRS?

Single Responsibility 

Single Responsibility is a computer programming principle. It states that every module or class should have responsibility for a single part of the functionality provided by the software. Therefore, all entities are each a Single Responsibility.

Benefits of Single Responsibility:

  1.  It makes it easier to edit and add functionality to a class/model that has a single responsibility 
  2. Will achieve loosely coupled application
  3. Independent of framework
  4. Code is more readable and understandable

This is how I segregate the
Command and Query Responsibility Segregation pattern

[ApplicationName].Core.Application

As you can see above, I have a Customers folder and inside that folder contains the commands, models, queries, and validators.

7

In each query and command, exists an actual command or query and a handler for each type.

For example in my case, I have a “CreateCustomerCommand.cs'” and “CreateCustomerCommandHandler” in the Commands folder. I also have “get” classes which are structured similarly in naming convention; “GetAllCustomersQuery.cs” and “GetAllCustomersQueryHandler.cs“.

I hope you understood this convention of naming the commands and queries you will need for your application.

The Commands are for Creating, Updating and Deleting objects/entities. The queries are for searching and getting data back out from the database.

An entity, is basically a “thing“. It can be anything . An entity could be a customer, a book or a coffee.

Entity definition for you haters, (hating on my software definition)

Yes, copied and pasted right from google! Anyway…

MediatR – Jimmy Bogard

So this guy Jimmy did a great job on implementing a library for the function of CQRS pattern. Benefits include:

  • Simple mediator implementation in .NET
  • In-process messaging with no dependencies.
  • Supports request/response, commands, queries, notifications and events, synchronous and async with intelligent dispatching via C# generic variance.
  • Any block can opt into these alignments. The embed block has them also, and is responsive out of the box:
Definitely watch this video, it is great!!! Jimmy and the team does a great job explaining CQRS!

Using MediatR in ASP.Net Core was slightly tricky, not many out there with the correct implementation. It actually is very simple, but it took me some time to figure it all out. (I’m still a newbie in the .NET Framework)

Here is some code for in the StartUp.cs class you can use to register the MediatR service:

// ADD MediatR
services.AddMediatR();
services.AddMediatR(typeof(CreateCustomerCommand).Assembly, typeof(CreateCustomerCommandHandler).Assembly);

See what I did there uptop, I registered the Command and the Command Handler

Don’t forget to do this!

The controllers in the MVC model will reference these commands, queries. 

The beauty is that MediatR handles the requests and the pipeline.

A “CreateCustomerCommand.cs” implementation:

namespace QAEngine.Application.Customers.Command
{
  public class CreateCustomerCommand : IRequest
  {
    public string Id { get; set; }
    public string Title { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Address { get; set; }
    public string City { get; set; }
    public string Region { get; set; }
    public string PostalCode { get; set; }
    public string Country { get; set; }
    public string Phone { get; set; }
    public DateTime AccountCreated { get; set; }
    public DateTime DateOfBirth { get; set; }
  }
}

A “CreateCustomerCommandHandler.cs” implementation:

namespace QAEngine.Application.Customers.Command
{
 public class CreateCustomerCommandHandler : IRequestHandler
 {
   private readonly QAEngineDbContext _context;  
   public CreateCustomerCommandHandler(QAEngineDbContext context)
   {
     _context = context;
   }

    public async Task<CustomerModel> Handle(CreateCustomerCommand 
    request, CancellationToken cancellationToken)
    {
        var entity = new Customer
        {
            CustomerId = request.Id,
            Title = request.Title,
            FirstName = request.FirstName,
            LastName = request.LastName,
            Address = request.Address,
            City = request.City,
            Region = request.Region,
            PostalCode = request.PostalCode,
            Country = request.Country,
            Phone = request.Phone,
            AccountCreated = request.AccountCreated,
            DateOfBirth = request.DateOfBirth.Date
        };

        _context.Customers.Add(entity);
        await _context.SaveChangesAsync(cancellationToken);
        return CustomerModel.Create(entity);
    }
  }
}

Finally, Here is my Customer controller, where I utilise these beautiful implementations <3

    [HttpGet()]
    public Task<List<CustomerListModel>> ViewCustomers()
    {
        return Mediator.Send(new GetCustomerListQuery());
    }


    [HttpGet("{id}")]
    public async Task<IActionResult> FindACustomer(string id)
    {
        return Ok(await Mediator.Send(new GetCustomerModelQuery { Id = id }));
    }


    [Authorize]
    public IActionResult NewCustomer()
    {

        return View();
    }

    [Authorize]
    [HttpPost]
    //noteToSelf = FromForm means from the bloody form not [FromBody]
    public async Task<IActionResult> NewCustomer([FromForm]CreateCustomerCommand command)
    {


        return Ok(await Mediator.Send(command));

    }

    [HttpPut("{id}")]
    public async Task<IActionResult> UpdateCustomerDetails(string id, [FromBody]UpdateCustomerCommand command)
    {
        if (command == null || command.Id != id)
        {
            return BadRequest();
        }


        return Ok(await Mediator.Send(command));
    }

    [HttpDelete("{id}")]
    public async Task<IActionResult> DeleteCustomer(string id)
    {
        await Mediator.Send(new DeleteCustomerCommand { Id = id });
        return NoContent();
    }

Code is Poetry

G

👋

Read my journey: https://www.bilaalsblog.com/pilot-a-software-developers-journey-and-the-amount-of-coffees-consumed/

Microsoft Technology Stack Software Development C# ASP .NET Framework
MediatR                                                https://github.com/jbogard/MediatR 

22 Comments

  1. http://canadianorderpharmacy.com/ June 3, 2019 at 9:23 am

    Heya terrific blog! Does running a blog such as this require a large amount of work? I have no understanding of computer programming however I had been hoping to start my own blog in the near future. Anyways, if you have any ideas or techniques for new blog owners please share. I know this is off subject nevertheless I simply needed to ask. Kudos!

    1. admin October 9, 2019 at 10:10 pm

      Thanks!! 🙂

      YouTube is really great. There are multiple online websites that also provide education.

      Kudos!

  2. Socopa Corretora June 22, 2019 at 9:13 am

    Howdy this is kinda of off topic but I was wanting to know if blogs use WYSIWYG editors
    or if you have to manually code with HTML. I’m starting a blog soon but have no coding know-how so I wanted to get
    guidance from someone with experience. Any help would be enormously appreciated!

    1. admin July 9, 2019 at 4:02 pm

      Hello there,

      Yes blogs do use WYSIWYG editors.. WordPress is a great platform! and it always has been!

      What are you going to blog about?

  3. Tarik July 11, 2019 at 8:20 pm

    Hello,
    Very nice blog. I am trying to explore CQRS/MediatR approach for some time now.
    I always lack examples of some more complex scenario with CQRS/MediatR. I work on a relatively big enterprise project in healthcare that is ready for change. Do you maybe have experience with applications implemented in this pattern that have high and heavy traffic ? I am interested in cons of using in-process messages. Also healthcare data is very interconnected and sometimes I am not sure about separation.
    Thanks! Cheers!

    1. admin October 9, 2019 at 10:09 pm

      Hi Tarik

      Separation is always best. When you mention healthcare i think of micro services. These are services which are totally loosely coupled to one another. All micro-services contain their own endpoint in the API design as well as a direct route to the database. A micro-services architecture would be best suited for you since this architecture will provide both speed and reliability. Deploying micro-services to the cloud will further enhance the design and architecture.

  4. martinez August 7, 2019 at 6:03 am

    When s᧐meone writes an ρiece of writing he/she keeps the idea of a useг in his/her mіnd that
    how a սser can սnderstand it. So that’s why thіs piece of writing is perfect.
    Thanks!

    1. admin December 20, 2019 at 7:37 pm

      THANKS MARTINEZ

  5. Reggie August 29, 2019 at 9:39 pm

    Heya i’m for the first time here. I found this
    board and I find It really useful & it helped me out much.
    I hope to give something back and aid others like you aided me.

    1. admin December 20, 2019 at 7:35 pm

      thanks Reggie

  6. oprolevorter September 9, 2019 at 6:40 am

    Its such as you read my mind! You appear to understand a lot about this, such as you wrote the e-book in it or something. I believe that you could do with some percent to pressure the message house a little bit, however other than that, this is magnificent blog. A great read. I’ll definitely be back.

    1. admin December 20, 2019 at 7:36 pm

      thank you for great feedback!

  7. ABCya September 16, 2019 at 5:15 am

    When someone writes an post he/she maintains the plan of a user in his/her mind that how a user
    can be aware of it. Therefore that’s why this post is outstdanding.
    Thanks!

    1. admin December 20, 2019 at 7:36 pm

      THANKS ABCYA

  8. HariBeauden October 12, 2019 at 1:54 pm

    I read this article fully about the difference of most recent and preceding technologies, it’s amazing article.|

    1. admin December 20, 2019 at 7:36 pm

      thanks HARIBEAUDEN

  9. BellBig October 14, 2019 at 7:27 pm

    Hello. I have checked your bilaalsblog.com and i see you’ve got some duplicate content so probably it is the
    reason that you don’t rank high in google. But you can fix this issue fast.
    There is a tool that creates articles like human, just search in google:
    miftolo’s tools

  10. check this link right here now January 9, 2020 at 7:11 pm

    Pretty section of content. I just stumbled upon your website and in accession capital to assert that I
    acquire actually enjoyed account your blog posts. Anyway
    I’ll be subscribing to your feeds and even I achievement you access consistently rapidly.

  11. nike air max 270 January 13, 2020 at 11:22 am

    I as well as my buddies came checking the nice secrets located on your web blog and then the sudden I got an awful feeling I never thanked the site owner for them. The women became as a consequence thrilled to read through them and have now absolutely been taking pleasure in those things. Many thanks for simply being really accommodating and then for figuring out certain brilliant guides millions of individuals are really needing to understand about. My personal honest regret for not saying thanks to you sooner.

    1. admin January 13, 2020 at 12:14 pm

      Thank you for your great feedback, I hope my future blog posts creates the same impact on you and all my readers. 😀

Leave a comment

Your email address will not be published. Required fields are marked *