This is a sample implementation of ASP.NET MVC4, MongoDB and Ninject to act as a starting template if you are going to use these technologies in your project with a CQRS pattern.
If most of these terms look unfamiliar then this post is probably not for you: CQRS, Repository, Aggregate (of DDD), NuGet, Unit Testing, Dependency Injection, Document DB. Due to the scope of this post, I won’t be able to go in details in any of these topics as this is a direct implementation.
Greg Young did a few paragraphs intro on CQRS here: CQRS, Task Based UIs, Event Sourcing agh, if you want a simple intro I recommend at least reading the first half of Greg’s post (before the Event Sourcing).
Scope and Definition
In this post, I mean the plain-CQRS pattern and not the whole patterns that are associated with CQRS. Plain CQRS opens the door for other patterns such as Event Sourcing and ES is usually associated with CQRS. This is the plain CQRS with no other associated pattern.
Choice of Technology
I chose MongoDB due to its open licence policy and simplicity, Ninject due to its licence, simplicity and
Ninject.Extensions.Conventions extension that makes my code DRYer.
I could have chosen SQL Server, but for simplicity reasons and to get the idea across, Document DBs are easier to work with. You could also tweak this sample implementation to work on an RDBMS as long as you get the repository right.
This is a sample implementation of ASP.NET MVC4, MongoDB and Ninject to act as a starting template, in case you are going to use these technologies in your project with a CQRS pattern.
This is meant to be a trivial application, so that the focus is shifted from the features to the MVC with CQRS pattern. The application:
- Enables querying the tasks. When the user clicks “Query”, if the Completed is selected, it will display completed tasks and if it is not selected, it will display uncompleted tasks. This is meant to represent the start of a CQRS’s Query.
- Checking or unchecking any checkbox in the “Completed?” column will update the task, via Ajax. This is meant to represent the start of a CQRS’s Command.
- Has no way to add or delete tasks. To load sample tasks into the DB, I have included, in the download, a MongoDB script that will populate the DB.
Why using CQRS with MVC?
I recently wrote You should unit test your controller, NOT!, where I gave guidelines that an MVC controller should have almost no code, so it doesn’t even require unit testing, but it is really difficult to show how to achieve this within the scope of that post.
Using CQRS enforces better separation of concerns and produces an almost-empty controller, where the viewmodel turns to a query, when getting data or turns into a command, when posting data.
The diagram above is a sketch of the implementation of the solution, it will get clearer when you progress through the post and read the source code.
First, whenever, you notice the use of “AT” in the namespace, you can replace that with your company name, as you’ve already concluded, ehmm, AT are my initials.
The solution is using VS 2012 and has 4 projects:
AT.Core: This is where the infrastructure classes are, such as the CQRS infrastructure classes.
AT.SampleApp.Cqrs: Commands, command handlers, queries, query handlers, query results and domain classes. This is where your business logic is. This project references
AT.Core. In this sample project it has one sample query
TasksByStatusQueryand one command
AT.SampleApp.Cqrs.Test.Unit: Unit tests for the
AT.SampleApp.Cqrsproject. They follow the conventions specified in the The Art of Unit Testing: with Examples in .NET by Roy Osherove, which I recommend you read, it is a bit outdated, however, there is a newer version being cooked, while writing this post.
AT.Web.Website: ASP.NET MVC4 project that references
I felt the best way to show the pattern, is to progress in the code as if I am debugging and show what is happening in each stage, I found this is the fastest way to learn, we spend half our lives as debugging debugging!
Command & Controller
The post request reaches the
ChangeTaskStatus action method and becomes a command:
Starting by the easier bit of the
ChangeTaskStatus method, the action method returns a HTTP code to the client to say that everything is fine.
_commandDispatcher.Dispatch takes a command and relies on the dependency injection to find a handler for this command, in this case, it will match the
Why relying on dependency injection rather than calling the command handler directly? Simple answer: decoupling. The controller doesn’t know much what is happening, it is just dispatching (some calls it publishing, but publishing might convey an async call or a bus call) a command “to whom it may concern” and the proper handler will take it and processes it.
_commandDispatcher is injected into the controller as well, we will see what it does in more details, but before that lets look at the dependency injector code, for this, I have used Ninject and Ninject.Extensions.Convention from NuGet, this is the kernel code that I’ve used:
BindDefaultInterface is simply saying bind
Something by convention, so, the first line injects the dispatchers into the controller.
Now, this dispatch method, how does it work? How does it match the command to its handler?
_kernel is Ninject, it is querying, at run-time, the handler of the passed command and then calling its
Execute method to pass it the command.
You’ve got to like the fact that dependency injectors promote decoupling, but your modules become coupled to them! Maybe we need a second-level dependency injector to decouple the first one. But, Ninject has a cool logo, so I don’t mind my modules depending on it 🙂
This is where the business logic lives. The handler might mutate a state, save to the DB (or more accurately, persists through a repository), calls another handler, etc…
This is the
ChangeTaskStatusCommandHanlder, Execute method:
Please keep in mind, what we are doing here as a business logic is super simplistic and doesn’t show the true power of the CQRS pattern, but it does give you an idea.
Binding via Ninject (this code will apply to all my handlers, not just this one):
I have used MongoDB as a storage media, which you can NuGet. Also, rather than implementing the popular Repository DDD pattern myself, one good chap implemented it for us for MongoDB and packaged it as NuGet, look at NuGet for MongoRepository. I am simply using it as-is. You could see that from the previous code above. I am using the following Ninject code to bind to it:
This is a simple aggregate and I am persisting it as a document in MongoDB:
The query has a similar path to the command, with the following differences:
The controller is calling the
_queryDispatcherexplicitly and not implicitly like the
- The query is two ways, the query and its results while the command is one way.
- There are much more differences, but I am looking at the differences from this project point of view.
I hope that I was able to illustrate the diagram above, feel free to ask me in a comment if I made a mistake or if you have a question.
Let’s recap on the steps that the command of CQRS was implemented.
- Command is triggered by the view.
- Command reaches the action method.
- The action method dispatches the command to a handler.
- The handler takes the command and does some business logic then persists it through a repository.
This is only the basic and the first building block in your CQRS application. You will probably add other CQRS related pattern on top of this. Here are some ideas to polish your architecture:
You might want to have a Base Controller and inject your dispatchers into it. Something like this:
Now, you have seen the basic pattern, what about looking further: Here is another good article that has a different focus to the stuff I’ve discussed here: Introduction to CQRS.
Enhancing the basic Architecture
There is no logging, there is no error handling, ofcourse, as this is not meant for production, it meant to be a sample, make it mainstream 🙂
The results? Controllers are nearly empty, DRY code and a pattern that is open for unit testing. Obviously, the amount of code is over killing for such a small application, but this is only to trigger your software design imagination so you could apply this pattern to a real-life application (obviously not by forcing the pattern if it doesn’t fit).
I hope I made somebody’s day, if you like this then do let me know in a comment so I would be encouraged to write more. While I tried to keep it to a minimum, this was longer than what I wanted it to be. Note that the source code in the download area contains the complete code.
I am open for suggestions to change for the better, do let me know your ideas in a comment.
Using Visual Studio 2012 Ultimate. I had to delete all the Nuget files to keep the file size to the minimum, it will probably ask you to download these packages from NuGet when you try to build it.
I tried to ensure that the information posted here are up to date and accurate, however, I do not hold any responsibility to any damages that might occur from using or misusing the information and the posted code.