An Introduction to PseudoCQRS
Command Query Responsibility Segregation (CQRS) is a pattern that was first described by Greg Young (http://codebetter.com/gregyoung/). You can read about the CQRS pattern here http://martinfowler.com/bliki/CQRS.html and here http://cqrs.files.wordpress.com/2010/11/cqrs_documents.pdf
A key concept of the CQRS pattern is that the state of your application is determined based on the events that have happened in the system. This differs from a “standard” N-Tier application where the state of the application is stored in the data store.
In a standard N-Tier application, if you wanted to create a customer you would create a Customer object, and then save that object to the database via some sort of repository (probably via an ORM such as NHibernate). If you then to update the address you would use retrieve the customer from the repository, update it, and then save it via the repository Save method again.
With CQRS, the state of the customer object is held in memory, and the things that you persist to the data store are the actual events that occurred in the system that affected that customer. As you have a record of all those events, if you shut the application down and then start it up again, you can just run through all the events to restore the state of the Customer object, and the rest of the system.
PseudoCQRS was created because we wanted to apply the CQRS pattern to an existing application - one that already has all the state information stored on a database. It was not going to be possible to refactor the application to use a "Pure" CQRS implementation, but we wanted to use the clear segregation between the "Command" side and the "Read" side of the app. So, PseudoCQRS was born.
PsuedoCQS is written in C# and is primarily aimed at Asp.NET MVC applications (versions 3 or 4).
The PseudoCQRS Architecture
As per the CQRS pattern, there are two sides to the PseudoCQRS architecture - the "Command" side and the "Query" side. This separation is shown on the diagram below:
As you can see from the diagram, PseudoCQRS is split into two sides; the “Query” side and the “Command” side.
This aligns with the CQRS pattern, which describes the fact that there are two main things your users do within your application – they look at data that is already in there (the “Query” side) and they execute commands which affect that data (the “Command” side).
The Query Side
In the web applications that we write, there are always a set of screens that users use to have a look at the state of their data. Things like “List all the customers”, “Show the details of one customer”, “Show a particular customer’s financial statement”. These screens rarely show all and ONLY all of the data regarding a particular entity within the domain. For example, in the case of the “List all the customers” screen, we only need to show their first name, last name, perhaps their email address and phone number. We don’t need to show their full postal address, the notes field for the customer, their date of birth etc – we just want a subset of the data.
Similarly, on the “Show the details of one customer” page, we need not only all the data from the Customer entity, but we might need some data from OTHER entities too – the country that they live in, or the name of the saleman who first approached this customer, or perhaps all the notes from recent interactions we’ve had with them. So again, we can’t just draw data from the customer entity – we need additional data.
This is the case in almost every screen in our applications – there is some “custom” set of data that we require in order to display the screen.
This is not a new concept in MVC applications – indeed, this is the “M” of MVC – the “Model”, or, as it’s more often referred to, the “ViewModel”.
This ViewModel will be specific to the particular View (ie, the screen) and will probably not be reused in any other screens (a slight caveat here is that there may be PORTIONS of the ViewModel that could be reused across screens – for example, an AddressViewModel or the like), so in PseudoCQRS we take that to the extent that for each ViewModel there is an individual “ViewModelProvider” which is responsible for creating that ViewModel.
ViewModelProviders use a combination of custom SQL statements and ORM queries to retrieve all the data required for the ViewModel, and to build that ViewModel up and return it. Indeed “pure” CQRS goes even further and suggests that you might even have one flattened table per screen that you fill when commands are executed but then can read straight out of on the Query side, so as to make it blazingly fast to query the database. We don’t go quite that far, but we do create custom queries for each ViewModel we need. We usually then use an open source project called “SqlObjectHydrator” to quickly and easily convert those queries into our ViewModels, but we do have instances where we do ORM queries which are then sculpted into the ViewModel as well. The method of building the ViewModel is not important – what is important is that for each View there is one ViewModelProvider which builds up one ViewModel which contains all the data that is required for that View.
This pattern allows us to very specifically concentrate on writing what we need in order to display the data that we need to. There is no concern over reusing bits and pieces of view based objects, which we have found quickly becomes very messy – instead each View, ViewModel and ViewModelProvider has a single concern and does that single concern very well, and very quickly.
Once the ViewModel has been built by the ViewModelProvider, it is passed to the controller that will display it. We have created three base controllers which we use – a BaseReadController, a BaseReadExecuteController and a BaseExecuteController. Each of these base controller has just one action in it – an “Execute” action. ReadControllers just display views (for example, “List Customers”), ExecuteControllers just execute commands (for example, “Delete a customer”) and ReadExecuteControllers do a bit of both (for example, “Display a customer for editing and the execute the command necessary to process that edit).
There is no real requirement to use the base controller that we’ve created, but we find it helps to align the vertical slices of functionality in a better way – one controller, one view, one viewmodel, one viewmodelprovider.
The Command Side
Besides viewing the state of their data, the other thing that users need to do with an application is to alter that state. This is done via the Command side of PseudoCQRS.
Again we use our base controllers for this – our BaseExecuteController for things that are just commands (“Delete this customer”) and BaseReadExecuteController for things that need to display some data first and then execute a command (“Update this customer’s details”).
Execute type controllers accept a ViewModel, try to validate that ViewModel (via the standard MVC validation attributes, or whatever other validation framework you like – we use FluentValidation), and if it validates correct, maps the ViewModel onto a Command and then puts that Command onto the CommandBus to be executed.
The CommandBus receives the command and first runs any validation rules necessary in order to validate the command. These validation rules are business logic type rules – things like “Don’t allow a customer to be deleted if they have pending orders” or “Only allow certain users to delete customers”). The CommandBus Runs these validation rules on the command and if the validation rules all pass, it then looks up the CommandHandler for a particular command.
If it finds a CommandHandler for the Command (ie, something that implements ICommandHandler<T> where T is the type of the Command) it passes the Command to that hander for execution.
The CommandHandler then deals with processing that command. That will usually involve some ORM queries. For example, an UpdateCustomerCommand will have an UpdateCustomerCommandHandler which will need to pull the existing customer from the database via the ORM, update whatever properties it needs to on the Customer entity and then save that Customer back to the database via the ORM.
The other thing that a CommandHandler may do is to publish “Events” to the EventPublisher. For example if a customer were updated, the UpdateCustomerCommandHandler might publish a “CustomerUpdatedEvent” which contained the details of the customer that was updated and the updates that were made. Objects can then subscribe for notification of these events (by implementing the IEventSubscriber<T> interface, where T is the type of the event). EventSubscribers can then do things like email administrators to inform them of the change, or record the history of the change to the database, or send an SMS to the customer when they place an order etc etc. They can even do things like create “flattened” data for the read side of the application, so that side can be more efficient. For example, if a customer creates a new order, and on the customer list screen you always display each customer’s outstanding balance, you could use an EventSubscriber to calculate that outstanding balance and “Cache” it on the Customer table whenever a pertinent event occurred (OrderPlacedEvent or PaymentMadeEvent). That way, when your ViewModelProvider needs to get that data, it doesn’t have to constantly recalculated the customer’s balance when displaying the list – it can just grab the data from the outstanding balance cache.
We wrote PseudoCQRS in order to allow us to use the very clear separation of concerns that the CQRS pattern offers, but while able to reuse the existing data structure (and much of the existing code) for a legacy application. We have since used it to write a completely new application as well, and it is working very well for us.
This article serves as a summary of the architecture. The next article which descibes the query side of PseudoCQRS can be found here:
Pseudo CQRS: The Query Side
PseudoCQRS is an open source project, and the code can be downloaded from GitHub, here: https://github.com/LiquidThinking/PseudoCQRS
Included in the source code is a sample application that implements the "Create Dinner" feature of the NerdDinner sample created by Scott Hansleman for demonstrating the functionality of Asp.NET MVC.
The package is also available on NuGet (package names PseudoCQRS and PseudoCQRS.Mvc4)
How to use PseudoCQRS
- Create an empty asp.net mvc web application project
- Install PseudoCQRS package via Visual Studio's Package Manager Console => install package ( PseudoCQRS | PseudoCQRS.Mvc4 ) for mvc framework 3 or 4.
Pseudo CQRS has no external dependencies other than some standard system assemblies, and System.Web.MVC.dll (version 3 or 4).