I’m building a website which has two basic workflows:
- Getting and displaying data from the database.
- Inserting and updating some data.
In other words I have Queries and Commands. I’m not going to talk what is the “query command pattern” - that you can read in Ayende’s “Limit your abstractions” posts. I am going to talk about a nice way to implement that pattern in your MVC application.
The implementation is pretty easy: if you need to query something you create a query class that does it. If you have to insert or update some data then you create a command class. The controller will execute commands and queries directly from it’s actions, no need no create a BL layer, DAL or repository of some kind.
First we need an abstract command class
The Command class a single method “Execute” that receives the session as a parameter. The Command class supposed to handle a business logic that creates, updates or deletes something in the application that’s why it has a void as a return type.
When I create the command I pass it my model, throw in some validations and finally use the received session to save the entity. Note that the command should not return a result. It should succeed or fail.
Same as the command first I’ll create an abstract query class a single method:
As oppose to the command class, the query has to return a result (T).
How to use them
So now we know how queries and commands look like, all that’s left is to use them.
The controller is responsible for executing the commands and the queries according to the action scenario.
The easiest way will be creating the command or the query in the controller and simply execute them.
However that’s not really testable since we don’t really want to execute our commands or queries. Furthermore it just looks bad.
We need to wrap the commands/queries so that we could mock them easily (and make the code look better).
In order to wrap the queries and the commands we’ll create “CommandExecuter” and “QueryExecuter” with a single method “Execute”.
The base controller will be ctor injected with both of them and will implement two methods “ExecuteCommand” and “ExecuteQuery” which receive a command or a query and call it Execute method.
Now when we want to execute a command or a query we’ll call the proper method and pass it the right parameter.
So what we gained?
1. A single command for every action and a single query for every … query.
2. Every command/query has its own logic but they all implement “Execute” method and the base controller just call it from a single place.
3. The deriving controllers are substitutable for their base type and use the BaseController ExecuteCommand or ExecuteQuery.
4. We have two different “Execute” methods, a void one and one which returns a result. Every command/query implements just the one they need and not forced to implement both.
5. Dependency injecting the command and query executers to the controller’s ctor.