A Developer's Guide to CQRS Using .NET Core and MediatR
1. Customize appearance
A Developer's Guide to CQRS Using .NET Core
and MediatR - DZone Web Dev
In this article, we discuss how to implement the CQRS
pattern in a .NET Core application with MediatR for cleaner
application architecture.
by
Faris Karcic
·
Jun. 22, 20
·
Web Dev Zone
·
Tutorial
Join the DZone community and get the full member experience.
Join For Free
“What is CQRS?” you might ask. I hope you didn’t think you were going
to get a definition because that’s what Wikipedia is for. Instead, what
I’m hoping to achieve with this blog post is to help you understand
CQRS through some practical examples.
I will assume you’re either a beginner or someone who is unfamiliar
with this topic, so maybe you get scared whenever you run into these
big programming acronyms and concepts. I myself have been there,
so I’m here to help you figure it out in the easiest way possible.
Before we get talking about CQRS, we need to understand a few
concepts, such as Clean Architecture, for a better understanding. If
you are already familiar with Clean Architecture, then feel free to skip
onto the next section. If you are one of those people reading this blog
who dislikes theory and just want to get your hands on the code, I
encourage you to be patient and try and grasp these concepts and
patterns as they will prove to be helpful in the end.
In this blog, I’ll lead you through a step-by-step tutorial so you learn
both about CQRS and also end up with a beautiful project structure
2. that you can brag to your friends about. You may also learn an
additional trick or two. At the end of the blog, I’ve provided a link to
the entire solution.
Clean Architecture
Before tackling the concept of CQRS let’s learn a bit about Clean
Architecture.
Why?
Because combining this duo gives us a pretty nice base for further
development. Clean Architecture is all about layers and boundaries
and creating a clean project structure just as the name itself implies.
We can see how these layers form one solution. It is important to
know that the outer layers depend upon the inner layers and not vice
versa.
Domain
In a perfect world, this layer wouldn’t have any dependencies, and it
would only contain entities, value objects, and maybe some Domain
level custom exceptions and entity logic. This layer can be shaped by
following the Domain-Driven Design guidelines. I would recommend
that you explore these guidelines in-depth. Since it’s a broad subject
I’ll leave it up to you.
Application
3. Together with the Domain layer, the Application layer forms the Core
of the solution that should be able to operate and provide business
logic independently from outer layers and depend solely upon the
Domain layer. It contains all of the good stuff, such as the business
logic (use cases), DTO’s, interfaces, and all of the CQRS stuff that we
will be discussing later.
Infrastructure
This is the layer where all of the communication logic with the outside
systems should be implemented such as sending emails,
communication with 3rd party API, etc. It only depends on the
Application layer. It can also contain persistence logic if it’s not overly
massive and/or complex.
Persistence
Compared to the Infrastructure layer, this layer also holds the logic for
communication with outside systems, but its specific purpose is to
communicate with databases. All of this logic can also be placed
under the Infrastructure layer. This layer only depends on the
Application layer.
Presentation
This is the interactable layer (by the outside world) which allows
clients to get visible results after requesting data. This layer can be in
the form of an API, console application, GUI client application, etc.
Like Persistence, it also depends only on the Application layer.
Now, since you have this quick overview of the architecture, we can
move forward to explore what CQRS is all about.
Let's Dive in
Have you ever experienced having to tweak some part of the logic or
models and upon finishing that task you realize that you blew up half
of the app? Or have you ever had to fix some bug (created by some
4. other developer of course) and then you go strolling through the
codebase searching for some specific part of logic but it’s hard to find
because it’s all spaghetti code? Or maybe the number of users on
your application has drastically increased, your current machine can’t
handle it anymore, the “scale up” button is greyed out because it was
so long ago that you already reached a top-level machine, you think of
balancing load with microservices, but you do a facepalm because
you know how much effort and time it will take to refactor all of that
spaghetti?
That’s what CQRS strives to solve!
CQRS stands for Command Query Responsibility Segregation and my
initial thought when I was learning this for the first time was: “Well
this name doesn’t help very much in understanding this” even though
it does when you start understanding the concept behind the name.
So the name basically is all there is: Let’s separate responsibilities of
commands & queries.
Then the next question arises, “What are commands and queries?”
Well, it’s rather simple and I will use CRUD operations as an example.
CREATE, UPDATE, and DELETE are methods used to tell the system to
insert, change, or remove something. As you’ve probably already
figured out, you are giving out commands. While with the READ
method you just want to get some data, and yes that’s a query, just
like when you query the database.
5. Now that we have some basic idea of what CQRS should do, we come
to the following question: but how can we use all of this in practice?
Which then brings us to a more specific question - How do I separate
these responsibilities?
That’s the next thing we are about to tackle.
CQRS in Practice
Let’s take a look at how CQRS looks in practice.
For now, let’s say we have an Application layer with the business logic
separated into use cases, or rather services. Perhaps you would have
a service for forum posts that would contain all of the logic regarding
forum posts and may be dependent upon other services. In addition,
this service could possibly be reused somewhere else.
It would look something like this:
There may be issues with this approach down the line when you need
to adjust a method in some service to adhere for a second service
which could break logic in some other third service where the first
service is used. You’ll end up with a headache since you need to
adhere to multiple cases and then figure out the way to adjust logic
for all these edge cases.
6. Or maybe you want to separate the application into microservices
until you realize how hard it will be because of the intertwined logic?
The CQRS pattern solves these problems and has many pros. Of
course, nothing is perfect, so the CQRS pattern also has its cons such
as not being totally DRY (Don’t Repeat Yourself) and managing it
would take a bit more time for some global changes.
Now let’s see how and why.
The CQRS structure would look something like this:
As you can see, every one of these classes has only one responsibility
and they aren’t reused. Every single one of them has its own models,
even though they might be alike or exact copies of other models.
However, programming and project architecture are subjective things
so you can combine approaches by having some reusable common
things. All of this separation makes it easy for us to find issues and
not ruin the rest of the codebase by fiddling with something. As well, it
makes it easy to extract microservices from code eventually.
Additional Nuggets Used
7. Check out some additional nuggets I used:
GitHub Codebase
The entire project can be found here.
Conclusion
After reading this blog, I hope that you’ve gained a better
understanding of CQRS and are excited to take on new challenges.
Personally, for me, CQRS is the way to go and there is no better way to
organize your project, subjectively speaking, until the next new big
programming acronym comes around to do bigger and better things.
Thank you for your patience for going through this with me and I wish
you good luck and happy coding!
You can find the original blog source here.
Topics:
cqrs,
c#,
dotnet,
clean architecture,
programming,
tutorial
Published at DZone with permission of Faris Karcic.
See the original
article here.
Opinions expressed by DZone contributors are their own.