CQRS Pattern With C# (Part 1)

Understand CQRS pattern in a real world application

Abdelmajid BACO
5 min readJul 7, 2020
CQRS Pattern with C#
Image from Pexels

CQRS is the acronym for Command Query Responsibility Segregation. The core idea of this pattern is to separate Read and Update operations by using different models to handle the treatment. We use commands to update data, and queries to read data.

In this article I’ll aim to clarify all parts of CQRS pattern with pretty schema and code example.

Traditional Architecture

The following schema shows a traditional architecture used to query and update a database. The same model is used to write and read data.

Command and Query with traditional architecture (From Microsoft Docs)
Command and Query with traditional architecture (From Microsoft Docs)

This architecture is perfect for a small project, but in more sophisticated applications, it will be laborious to implement new features. For example, the application needs to display some information on different screens. So, many queries are requested to database, then all responses are mapped to a specific data transfer object. Another example is when the application tries to update model with some data validation, maybe a complex business rules. In conclusion, the model does many things!

You will notice that the model becomes more and more complicated. To avoid this problem, let’s look at the contribution of the CQRS pattern in the next chapter.

New Architecture With CQRS

The CQRS pattern proposal, consists of separating the read and update / write operations into different models. As shown in the following schema,
two models are involved in this architecture, the first manages the read operations and the second manages the write operations.

Command Query Responsibility Segregation architecture (From Microsoft Docs)
Command Query Responsibility Segregation architecture (From Microsoft Docs)

According to Microsoft documentation, the CQRS pattern must follow the three principles below:

1) Commands should be task based, rather than data centric. (“Book hotel room”, not “set ReservationStatus to Reserved”).

2) Commands may be placed on a queue for asynchronous processing, rather than being processed synchronously.

3) Queries never modify the database. A query returns a DTO that does not encapsulate any domain knowledge.

Now, let’s take an example to explain all the concepts of CQRS.

Real World Application

I’ll try to create a simple application that follows the Domain-Driven Design (DDD) principles and use CQRS pattern to perform Read and Update operations. As shown in the following schema, the application is composed of four layers, UI, Application, Domain and Infrastructure.

CQRS Architecture in Domain-Driven Design (DDD)
Lite CQRS Architecture

The Application Layer encapsulates the use cases and features of the business. It provides communication with Domain and Infrastructure layers, it also includes commands and queries the two parts of CQRS.

Query Dispatcher and Command Dispatcher are used to choose a proper handler for a giving query/command and execute it.

The Query handler gets data from the repository and map the result with the appropriate DTO object. The Dispatcher is responsible to return data to UI.

The Command handler tries to validate data before making any changes to the system.

Here is the solution structure:

Domain-Driven Design (DDD) solution with CQRS pattern
Solution structure

To manage commands and queries operations, I’m using the following interfaces:

Interfaces to manage queries
Interfaces to manage commands

Now, let’s try to explain one use case of the application, for example:

“Add a New Product”: this scenario is a command operation because it’ll make a change to the system.

First, I created a class called AddNewProductCommand, this class is a simple DTO object that implement ICommand.

Command object

Secondly, I created a class called AddNewProductCommandHandler that implement ICommandHandler<T> and used AddNewProductCommand as input parameter to perform the user scenario.

Please notice that commands maybe processed asynchronously. To simplify this example I used an empty task to make the handler asynchronous.

Command object handler

Thirdly, I created a class called CommandDispatcher that implement ICommandDispatcher and used to choose a proper handler for a giving command. The handlers are injected using Microsoft.Extensions.DependencyInjection.

Command dispatcher

Finally, in the code below, we can execute the command to add a new product. Another way to invoke this command is described on my project on GitHub, it’s about WebApi.

Call dispatcher to perform commands

For other Scenarios, you can check the source code available on GitHub.

Conclusion

Implementing CQRS in your application can maximize its performance, such as reusability, testability, maintainability, security and scalability. However, it takes a lot of work to manage different models!

But don’t worry, MediatR library is here to simplify implementation of CQRS. My article about MediatR library is available here:

Thanks for reading. I hope this article was helpful to understand CQRS pattern.

Learn More / Resources

--

--

Abdelmajid BACO
Abdelmajid BACO

Written by Abdelmajid BACO

Senior Full Stack .Net / Angular Developer, Cloud & Azure DevOps, Carrier Manager, Husband, and Father.

Responses (2)