Sponsor: Do you build complex software systems? See how NServiceBus makes it easier to design, build, and manage software systems that use message queues to achieve loose coupling. Get started for free.
This is a series of blog posts that demonstrate how to thin your controllers by implementing commands and queries using the MediatR library. For demonstration, I’m converting the MusicStore application that’s using ASP.NET Core MVC.
For more information on the purpose of this series, check out my initial post
You can get all the code for this entire series on on my fork of the MusicStore app GitHub
. If you have any improvements or suggestions, please create an issue or send a PR and I’ll be sure to include it in any of my blog posts.
For our first example, we are going to rewrite the HomeController Index action. I figured it’s a the entry point into our app, so no better place to start.
What is also helpful in this example is it is fairly straight forward. It contains some data access and in-memory caching prior to do view rendering.
Here’s what it looks like.
There are a couple packages we need to add to our project. We are going to be using MediatR as mentioned, however we are also going to add another package “MediatR.Extensions.Microsoft.DependencyInjection” by Jimmy Bogard (creator of MediatR). This will scans assemblies and adds handlers implementations to the container.
Your project.json dependencies section should look as follows
In our Startup.cs we need to register mediator in our ConfigureServices method. The “MediatR.Extensions.Microsoft.DependencyInjection” added an extension method “AddMediatR” which we can now call to register all our handlers we will be created.
Add the following in the ConfigureServices method
One of the ways I’ve explained Mediator pattern is like the post office (snail mail). When you want to send a message to someone, you send it to the post office and they route it to the physical location for that message. You don’t need to know how or where that location is, all you care about is giving it to the post office and let them do the work.
Instead of making a method call we are interchangeably going to create a message (object) and send it to the Mediator and have it figure how to create the appropriate handler and it dependencies and then invoke the handler.
Since our Home/Index method doesn’t require any parameters, our message is going to be pretty straight forward.
What we are doing is defining a class that implements IAsyncRequest. The first type parameter defines the return value from our handler. Meaning, when we send that message to the mediator what type do we expect in return.
Now we need to implement our handler. Our handler will accept the the message (Home) and return a List<Album>. What you will notice is I’ve for the most part taken the code from the controller and moved it to this handler.
One thing to notice is that our Handler’s constructor is taking dependencies (EF Context, Cache, AppSettings) that were originally defined in the Index method using dependency injection.
Now let’s go back over to our HomeController and use MediatR.
First thing we will do is inject the IMediator into the HomeController via the constructor. Then we will be calling MediatR with our Home message to get our list of albums.
That’s a very simple query endpoint that we moved our logic to a Query Handler using MediatR.
Next up we we will handle a command.
If anyone has any comments, suggestions or recommendations please leave comment or let me know on twitter.
3 thoughts to “Fat Controller CQRS Diet: Simple Query”
Some deep primal part of me loooves this. I don’t know if I should trust it, but I will anyway.
I especially like that as the series progresses, dependencies used by one, but not other controller actions will be broken off into the handlers so you don’t get that “monolothic constructor” feeling..