Print

Meanwhile... on the query side of my architecture

Command-query separation is a common concept in the software industry. Many architectures separate commands from the rest of the system and send command messages that are processed by command handlers. This same concept of messages and handlers can just as easily be applied to the query side of an architecture. There are not many systems using this technique and this article is an attempt to change that. Two simple interfaces will change the look of your architecture... forever.

In my previous post I described how I design the command side of my systems. The greatest thing about this design is that it provides a lot of flexibility and lowers the overall complexity of the system through the addition of one simple interface to the system. The design is founded on the SOLID principles and is brought to life with Dependency Injection (although DI is optional). Please read that post if you haven’t already, as this post will regularly refer to its content.

It’s funny that I encountered the command/handler design so many years ago but failed to understand why anyone would use two classes for one operation (one for the data and one for the behavior). It didn’t seem very object oriented to me and it was only after I experienced problems with the old design (message and behavior in the same class) that the potential of the command/handler design became clear to me.

With my business layer modeled uniformly and giving me great flexibility it then became clear that the same wasn't true for the part of the business layer that was responsible for querying. It was this dissatisfaction that triggered me to think about the design of this part of my application architecture.

Originally I would model queries as methods with clear names and group them together in a class. This led to interfaces like the following:

public interface IUserQueries
{
User[] FindUsersBySearchText(string searchText, bool includeInactiveUsers);

User[] GetUsersByRoles(string[] roles);

UserInfo[] GetHighUsageUsers(int reqsPerDayThreshold);

// More methods here
}

There is a variation of this pattern that a lot of developers use today in their applications. They mix this query class with the repository pattern. The repository pattern is used for CRUD operations. The following code may look familiar:

// Generic repository class (good)
public interface IRepository<T>
{
T GetByKey(int key);

void Save(T instance);

void Delete(T instance);
}

// Custom entity-specific repository with query methods (awkward)
public interface IUserRepository : IRepository<User>
{
User[] FindUsersBySearchText(string searchText, bool includeInactiveUsers);

User[] GetUsersByRoles(string[] roles);

UserInfo[] GetHighUsageUsers(int reqsPerDayThreshold);

// More methods here
}

Alongside the IUserQueries interface, my application contained interfaces such as IPatientInfoQueries, ISurgeryQueries, and countless others, each with its own set of methods and its own set of parameters and return types. Every interface was different, which made adding cross-cutting concerns, such as logging, caching, profiling, security, etc very difficult. I was missing the uniformity in the design that I had with my command handlers. The query classes were just a bunch of random methods, often grouped around one concept or one entity. No matter how hard I tried, it would end up looking messy and each time a query method was added both the interface and the implementation would need to be changed.

In my automated test suite things were even worse! A class under test that depended on a query interface was often only expected to call one or two of its methods, while other classes were expected to call other methods. This meant I had to do hundreds of asserts in my test suite to ensure a class didn’t call unexpected methods. This resulted in the creation of abstract base classes in my test project that implemented one of these query interfaces. Each abstract class looked something like this:

public abstract class FakeFailingUserQueries : IUserQueries
{
public virtual User[] FindUsersBySearchText(string searchText, bool includeInactive)
{
Assert.Fail("Call to this method was not expected.");
return null;
}

public virtual User[] GetUsersByRoles(string[] roles)
{
Assert.Fail("Call to this method was not expected.");
return null;
}

public virtual UserInfo[] GetHighUsageUsers(int requestsPerDayThreshold)
{
Assert.Fail("Call to this method was not expected.");
return null;
}

// More methods here
}

For each test I would inherit from this base class and override the relevant the method:

public class FakeUserServicesUserQueries : FakeFailingUserQueries
{
public User[] UsersToReturn { get; set; }

public string[] CalledRoles { get; private set; }

public override User[] GetUsersByRoles(string[] roles)
{
this.CalledRoles = roles;

return this.UsersToReturn;
}
}

All this meant I could leave all the other methods fail (since they were not expected to be called) which saved me from having to write too much code and reduced the chance of errors in my tests. But it still led to an explosion of test classes in my test projects.

Of course all these problems can be solved with the ‘proper’ tooling. For instance, cross-cutting concerns can be added by using compile-time code weaving (using PostSharp for instance), or by configuring your DI container using convention based registration, mixed with interception (interception uses dynamic proxy generation and lightweight code generation). The testing problems can be resolved by using Mocking frameworks (which also generate proxy classes that act like the original class).

These solutions work, but they usually only make things more complicated and in reality they are patches to hide problems with the initial design. When we validate the design against the five SOLID principles, we can see where the problem lies. The design violates three of the five SOLID principles.

The Single Responsibility Principle is violated, because the methods in each class are not highly cohesive. The only thing that relates those methods is the fact that they belong to the same concept or entity.

The design violates the Open/Closed Principle, because almost every time a query is added to the system, an existing interface and its implementations need to be changed. Every interface has at least two implementations: one real implementation and one test implementation.

The Interface Segregation Principle is violated, because the interfaces are wide (have many methods) and consumers of those interfaces are forced to depend on methods that they don’t use.

So let us not treat the symptoms; let’s address the cause.

A better design

Instead of having a separate interface per group of queries, we can define a single interface for all the queries in the system, just as we saw with the ICommandHandler<TCommand> interface in my previous article. We define the following two interfaces:

public interface IQuery<TResult>
{
}

public interface IQueryHandler<TQuery, TResult> where TQuery : IQuery<TResult>
{
TResult Handle(TQuery query);
}

The use of such  IQuery<TResult> interface is something that Udi Dahan mentioned back in 2007. So in fact this concept isn't new at all. Unfortunately, Udi doesn't go into much details in his article.

The IQuery<TResult> specifies a query message with TResult as the query's return type. Although this interface doesn't look very useful, I will explain later on why having such an interface is crucial.

Whereas a command is normally "fire and forget" and will update something in the system and not return a value, a query is the opposite, in that it will not change any state and does return a value.

Using the previously defined interface we can define a query message:

public class FindUsersBySearchTextQuery : IQuery<User[]>
{
public string SearchText { get; set; }

public bool IncludeInactiveUsers { get; set; }
}

This class defines a query operation with two parameters that returns an array of User objects. Just like a command, this query message class is a Parameter Object.

Parameter Object Refactoring Cue Card

The class that handles this message can be defined as follows:

public class FindUsersBySearchTextQueryHandler
: IQueryHandler<FindUsersBySearchTextQuery, User[]>
{
private readonly NorthwindUnitOfWork db;

public FindUsersBySearchTextQueryHandler(NorthwindUnitOfWork db)
{
this.db = db;
}

public User[] Handle(FindUsersBySearchTextQuery query)
{
return (
from user in this.db.Users
where user.Name.Contains(query.SearchText)
select user)
.ToArray();
}
}

As we’ve seen with the command handlers, we can now let consumers depend on the generic IQueryHandler interface:

public class UserController : Controller
{
IQueryHandler<FindUsersBySearchTextQuery, User[]> handler;

public UserController(IQueryHandler<FindUsersBySearchTextQuery, User[]> handler)
{
this.handler = handler;
}

public View SearchUsers(string searchString)
{
var query = new FindUsersBySearchTextQuery
{
SearchText = searchString,
IncludeInactiveUsers = false
};

User[] users = this.handler.Handle(query);

return this.View(users);
}
}
This model gives us a lot of flexibility because we can now decide what to inject into the UserController. As we’ve seen in the previous article, we can inject a completely different implementation, or one that wraps the real implementation, without having to make any changes to the UserController (and all other consumers of that interface).

Note this is where the IQuery<TResult> interface comes into play. It prevents us from having to cast the return type (to User[] in this example); it therefore gives us compile-time support when working with the query handler; it provides compile-time support when specifying or injecting IQueryHandlers into our code. If we were to change the FindUsersBySearchTextQuery to return UserInfo[] instead of User[] (by updating it to implement IQuery<UserInfo[]>), the UserController would fail to compile because the generic type constraint on IQueryHandler<TQuery, TResult> won't be able to map FindUsersBySearchTextQuery to User[].

Injecting the IQueryHandler interface into a consumer however, has some less obvious problems that still need to be addressed.

The number of dependencies if our consumers might get too big and can lead to constructor over-injection - when a constructor takes too many arguments (a common rule of thumb is that a constructor should take no more than 4 or 5 arguments). Constructor over-injection is an anti-pattern and is often a sign that the Single Responsibility Principle (SRP) has been violated. Although it is important to adhere to SRP, it is also highly likely that consumers will want to execute multiple different queries without really violating SRP (in contrast to injecting many ICommandHandler<TCommand> implementations which would certainly be a violation of SRP). In my experience the number of queries a class executes can change frequently, which would require constant changes into the number of constructor arguments.

Another shortcoming of this approach is that the generic structure of the IQueryHandler<TQuery, TResult> leads to lots of infrastructural code which in turn makes the code harder to read. For example:

public class Consumer
{
IQueryHandler<FindUsersBySearchTextQuery, IQueryable<UserInfo>> findUsers;
IQueryHandler<GetUsersByRolesQuery, IEnumerable<User>> getUsers;
IQueryHandler<GetHighUsageUsersQuery, IEnumerable<UserInfo>> getHighUsage;

public Consumer(
IQueryHandler<FindUsersBySearchTextQuery, IQueryable<UserInfo>> findUsers,
IQueryHandler<GetUsersByRolesQuery, IEnumerable<User>> getUsers,
IQueryHandler<GetHighUsageUsersQuery, IEnumerable<UserInfo>> getHighUsage)
{
this.findUsers = findUsers;
this.getUsers = getUsers;
this.getHighUsage = getHighUsage;
}
}

Wow!! That’s a lot of code for a class that only has three different queries that it needs to execute. This is in part due to the verbosity of the C# language. A workaround (besides switching to another language) would be to use a T4 template that generates the constructor in a new partial class. This would leave us with just the three lines defining the private fields. The generic typing would still be a bit verbose, but with C# there's nothing much we can do about that.

So how do we fix the problem of having to inject too many IQueryHandlers? As always, with an extra layer of indirection :-). We create a mediator that sits between the consumers and the query handlers:

public interface IQueryProcessor
{
TResult Process<TResult>(IQuery<TResult> query);
}

The IQueryProcessor is a non-generic interface with one generic method. As you can see in the interface definition, the IQueryProcessor depends on the IQuery<TResult> interface. This allows us to have compile time support in our consumers that depend on the IQueryProcessor. Let’s rewrite the UserController to use the new IQueryProcessor:

public class UserController : Controller
{
private IQueryProcessor queryProcessor;

public UserController(IQueryProcessor queryProcessor)
{
this.queryProcessor = queryProcessor;
}

public ActionResult SearchUsers(string searchString)
{
var query = new FindUsersBySearchTextQuery
{
SearchText = searchString
};

// Note how we omit the generic type argument,
// but still have type safety.
User[] users = this.queryProcessor.Process(query);

return this.View(users);
}
}

The UserController now depends on a IQueryProcessor that can handle all of our queries. The UserController’s SearchUsers method calls the IQueryProcessor.Process method passing in an initialized query object. Since the FindUsersBySearchTextQuery implements the IQuery<User[]> interface, we can pass it to the generic Execute<TResult>(IQuery<TResult> query) method. Thanks to C# type inference, the compiler is able to determine the generic type and this saves us having to explicitly state the type. The return type of the Process method is also known. So if we were to change the FindUsersBySearchTextQuery to implement a different interface (say IQuery<IQueryable<User>>) the UserController will no longer compile instead of miserably failing at runtime.

It is now the responsibility of the implementation of the IQueryProcessor to find the right IQueryHandler. This requires some dynamic typing, and optionally the use of a Dependency Injection framework, and can all be done with just a few lines of code:

sealed class QueryProcessor : IQueryProcessor
{
private readonly Container container;

public QueryProcessor(Container container)
{
this.container = container;
}

[DebuggerStepThrough]
public TResult Process<TResult>(IQuery<TResult> query)
{
var handlerType =
typeof(IQueryHandler<,>).MakeGenericType(query.GetType(), typeof(TResult));

dynamic handler = container.GetInstance(handlerType);

return handler.Handle((dynamic)query);
}
}

The QueryProcessor class constructs a specific IQueryHandler<TQuery, TResult> type based on the type of the supplied query instance. This type is used to ask the supplied container class to get an instance of that type. Unfortunately we need to call the Handle method using reflection (by using the C# 4.0 dymamic keyword in this case), because at this point it is impossible to cast the handler instance, since the generic TQuery argument is not available at compile time. However, unless the Handle method is renamed or gets other arguments, this call will never fail and if you want to, it is very easy to write a unit test for this class. Using reflection will give a slight drop, but is nothing to really worry about (especially when you're using Simple Injector as your DI framework, because it is blazingly fast).

I did consider an alternative design of the IQueryProcessor interface, that looked like this:

public interface IQueryProcessor
{
TResult Process<TQuery, TResult>(TQuery query) where TQuery : IQuery<TResult>;
}

This version of the interface solves the problem of having to do dynamic typing in the QueryProcessor implementation completely, but sadly the C# compiler isn’t ‘smart’ enough to find out which types are needed (damn you Anders!), which forces us to completely write out the call to Process, including both generic arguments. This gets really ugly in the code and is therefore not advisable. I was a bit amazed by this, because I was under the assumption that the C# compiler could infer the types. (However, the more I think about it, the more it makes sense that the C# compiler doesn't try to do so.)

There’s one very important point to note when using the IQueryProcessor abstraction. By injecting an IQueryProcessor, it is no longer clear which queries a consumer is using. This makes unit testing more fragile, since the constructor no longer tells us what services the class depends on. We also make it harder for our DI framework to verify the object graph it is creating, since the creation of an IQueryHandler implementation is postponed by the IQueryProcessor. Being able to verify the container's configuration is very important. Using the IQueryProcessor means we have to write a test that confirms there is a corresponding query handler for every query in the system, because the DI framework can not check this for you. I personally can live with that in the applications I work on, but I wouldn’t use such an abstraction too often. I certainly wouldn’t advocate an ICommandProcessor for executing commands - consumers are less likely to take a dependency on many command handlers and if they do it would probably be a violation of SRP.

One word of advice: When you start using this design, start out without the IQueryProcessor abstraction because of the reasons I described. It can always be added later on without any problem.

A consequence of the design based on the IQueryHandler interface is that there will be a lot of small classes in the system. And believe it or not, but having a lot of small / focused classes (with clear names) is actually a good thing. Many developers are afraid of having too many classes in the system, because they are used in working in big tangled code bases with lack of structure and the proper abstractions. The cause of what they are experiencing however isn't caused by the amount of classes, but by the lack of structure. Stop writing less code; start writing more maintainable code!

Tip: Although there are many ways to structure a project, I found it very useful to place each query class, its DTOs, and the corresponding handler in the same folder, which is named after the query. So the BusinessLayer/Queries/GetUsersByRoles folder might contain the files GetUserByRolesQuery.cs, UserByRoleResult.cs and GetUsersByRolesQueryHandler.cs.

Another fear of developers is long build times. Keeping the build times low is in my experience crucial for good developer productivity. The number of classes in a project however, hardly influences the build time. The number of projects on the other hand does. You'll often see that the build time increases exponentially with the number of projects in a solution. Reducing the number of classes wont help you a bit.

When using a Dependency Injection framework, we can normally register all query handlers with a single call (depending on the framework), because all the handlers implement the same IQueryHandler<TQuery, TResult> interface. Your mileage may vary, but with Simple Injector, the registration looks like this:

container.RegisterManyForOpenGeneric(typeof(IQueryHandler<,>),
typeof(IQueryHandler<,>).Assembly);

This code saves us from having to change the DI configuration any time we add a new query handler to the system. They will all be picked up automatically.

With this design in place we can add cross-cutting concerns such as logging, audit trail, etc. Or let’s say you want to decorate properties of the query objects with Data Annotations attributes, to enable validation:

public class FindUsersBySearchTextQuery : IQuery<User[]>
{
// Required and StringLength are attributes from the
// System.ComponentModel.DataAnnotations assembly.
[Required]
[StringLength(1)]
public string SearchText { get; set; }

public bool IncludeInactiveUsers { get; set; }
}

Because we modeled our query handlers around a single IQueryHandler<TQuery, TResult> interface, we can define a simple decorator that validates all query messages before they are passed to their handlers:

public class ValidationQueryHandlerDecorator<TQuery, TResult>
: IQueryHandler<TQuery, TResult>
where TQuery : IQuery<TResult>
{
private readonly IQueryHandler<TQuery, TResult> decorated;

public ValidationQueryHandlerDecorator(IQueryHandler<TQuery, TResult> decorated)
{
this.decorated = decorated;
}

[DebuggerStepThrough]
public TResult Handle(TQuery query)
{
var validationContext = new ValidationContext(query, null, null);
Validator.ValidateObject(query, validationContext, validateAllProperties: true);

return this.decorated.Handle(query);
}
}

All without changing any of the existing code in our system beyond adding the following new line of code in the Composition Root:

container.RegisterDecorator(typeof(IQueryHandler<,>),
typeof(ValidationQueryHandlerDecorator<,>));

If you're concerned about performance and worry that this would add too much overhead by wrapping query handlers that don't need validation with a decorator, a DI container such as Simple Injector allows you to easily configure a conditional decorator:

// using SimpleInjector.Extensions;
container.RegisterDecorator(typeof(IQueryHandler<,>),
typeof(ValidationQueryHandlerDecorator<,>),
context => ShouldQueryHandlerBeValidated(context.ServiceType));

The applied predicate is evaluated just once per closed generic IQueryHandler<TQuery, TResult> type, so there is no performance loss in registering such a conditional decorator (or at least, with Simple Injector there isn't). As I said, your mileage may vary when using other DI frameworks.

I’ve been using this model for some time now but there is one thing that struck me early on - everything in the system is either a query or a command and if we want, we can model every single operation in this way. But do we really want to? No, definitely not, mostly because it doesn’t always result in the most readable code. Take a look at this example:

public IQueryable<Order> Handle(GetRecentOrdersForLoggedInUserQuery query)
{
int currentUserId = this.userHandler.Handle(new GetCurrentUserIdQuery());

DateTime currentTime = this.timeHandler.Handle(new GetCurrentTimeQuery());

return
from order in db.Orders
where order.User.Id == currentUserId
where order.CreateDate >= currentTime.AddDays(-30)
select order;
}

This query method is composed of other queries. Composing queries out of other queries is a great way to improve modularity and manage the complexity of the system. But still there is something smelly about this code. Personally, I find the following example easier to read:

public IQueryable<Order> Handle(GetRecentOrdersForLoggedInUserQuery query)
{
return
from order in db.Orders
where order.User.Id == this.userContext.UserId
where order.CreateDate >= this.timeProvider.Now.AddDays(-30)
select order;
}

The previous sub queries are in this version replaced with the IUserContext and ITimeProvider services. Because of this, the method is now more concise and compact.

So where do we draw the line between using an IQuery<TResult> and specifying an explicit separate service interface? I can’t really define any specific rules on that; a little bit of intuition and experience will have to guide you. But to give a little bit of guidance, when a query returns a (cached) value without really hitting an external resource, such as the file system, web service, or database, and it doesn’t contain any parameters, and you’re pretty sure you never want to wrap it with a decorator (no performance measuring, no audit trailing, no authorization) it’s pretty safe to define it as a specific service interface. Another way to view this is to use this design to define business questions: things the business wants to know. In other words, use the IQueryHandler<TQuery, TResult> and ICommandHandler<TCommand> abstractions as the communication layer between the business layer and the layers above.

That’s how I roll on the query side of my architecture.

- .NET General, Architecture, Dependency injection - 23 comments / No trackbacks - §

The code samples on my weblog are colorized using javascript, but you disabled javascript (for my website) on your browser. If you're interested in viewing the posted code snippets in color, please enable javascript.

23 comments:

that is darn right scary how similar it is to our query architecture at my company! :-)

one thing i implemented was a cachequery attribute that we used for caching our query results.
Marco - 20 01 12 - 22:08

Hi. Thanks for nice article. Actually my English is not good, so I'm not sure I understand or not. Do you mean, we should use `Command` to `update`, `delete` and `create`, and use `Query` to `select`?
Amiry (URL) - 14 09 12 - 18:44

Hi Amiry, these patterns are especially useful in systems with business logic that’s more complex than simple CRUD operations. When looking closely at the requirements of a system, you will often find that a user's button click must do much more than just saving a single row in the database. Often multiple tables have to be updated, mails have to be constructed and sent, calculations have to be done, external systems have to be called, etc. etc. In that case it gets really useful to pack all business logic that happens after the 'button click' inside a command handler. If your system (or parts of the system), only consists of doing CRUD operations, you'd probably be better off by letting the presentation layer directly use repositories instead. Repositories could as well be decorated with cross-cutting concerns such as authorization, validation, logging, audit trailing, etc.
Steven (URL) - 15 09 12 - 18:15

Yes I understand now. Thanks to comment. But another question, if we need the command returns a result, what can we do? For example, login-command should return a boolean(e.g. login: yes / no). How can we achieve this?
Amiry (URL) - 15 09 12 - 20:06

If you need to return data from commands, take a look at this article: https://www.cuttingedge.it/blogs/steven/.. However, in the case of logging in a user, I don't think that's really suited for a command, since you are really asking a question here (while doing a side effect). Instead, I would use an IAuthorizationService or something like that.
Steven (URL) - 15 09 12 - 21:09

nice ;)
jgauffin (URL) - 10 10 12 - 09:14

Steven, thanks for this series. I have a question about testing.
With this approach, it is very easy to test that the BL uses a certain query / command.
But how do you test the query / command handler itself? I only see a way via integration tests but not via unit tests. Do you agree?
Daniel Hilgarth (URL) - 11 06 13 - 16:44

Hi Daniel, this series focuses on using the right abstractions and not so much on a particular handler implementation, although a simple example is given. For what it's worth, the article could have used a handler implementation with an embedded SQL statement.

The given handler example uses a unit of work that exposes an IQueryable<T>. IQueryable<T> is a leaky abstraction and this makes unit testing hard. I've written in the past about a solution (https://www.cuttingedge.it/blogs/steven/pivot/entry.php?id=84) but the fact remains that IQueryable<T> is a leaky abstraction and is hard to test.

But using an IQueryHandler<TQuery, TResult> or ICommandHandler<TCommand> abstraction in itself does not limit the testability of the handler implementation.
Steven (URL) - 11 06 13 - 20:28

Another very useful article. Thanks.
sean - 26 06 13 - 13:27

Hi Steven, great article. I've been looking for something like this for a long while now. Do you still use this approach or have you moved on to something even better now?

One problem I have with this approach is...if I was to have 2 layers i.e. "Application.Data" and "Application.Web" are they not tightly coupled because of "FindUsersBySearchTextQuery"?
Sam - 13 11 13 - 10:35

Hi Sam,

I use this pattern on a daily basis on the projects I participate in. It brings me much joy, great power, and extreme flexibility. I can't imagine creating any system without this pattern.

Your layers will not be tightly coupled because of the use of this pattern, on the contrary. If two layers communicate with each other, they will have to send data. They simply need to have some communication contract; they must agree on what messages to send and accept. You can't build a system without passing data from one layer to the other. So the communication contract is the absolute minimum amount of coupling you need between layers. FindUsersBySearchTextQuery is a message; it’s part of your data contract. On top of that data contract, the pattern defines just a single abstraction that describes how to communicate. This is the IQueryHandler<TQuery, TResult> interface. So the coupling is actually very low. I think it’s even safe to say that you can’t get a coupling that is lower than this.

Also note that although using DataTables as query messages and return types lowers the number of runtime types that you send between layers, this does not make the communication contract any smaller, since each sent and recieved DataTable is still expected to have a unique structure; each still has its own unique signature. Both the sender and receiver depend on this structure. When using the query/handler pattern, you make this contract explicit and add compile-time support to this contract.
Steven - 13 11 13 - 11:34

I can only second that. Since using that pattern, the architecture of my applications has increased a lot and my mental load when writing them has decreased.

Why? Because you simply need to take a dependency on the IQueryHandler interface and define the parameters of the query in a Query class. That's it. It reduces the mental load by changing the approach from "how to get the data" to simply *declaring what data you want and why you need that data*.

You can then later figure out, how you actually want to implement the query handler, whether it gets the data from a relational database or a web service.

That's another very positive aspect of this pattern:
You are finally able to *truly* abstract away the data store. Why? Because you declare what data you need and why you need it. With declaring the *why*, the query implementation knows exactly what data you need, so it can get all the data from the database needed for your exact scenario. This totally gets rid of all the problems lazy loading has, especially when trying to abstract the data store with an implementation of the repository pattern.
Daniel Hilgarth (URL) - 13 11 13 - 12:07

I know it is 2 years since you've written it, but I only found it just now -)

We have started using mediator pattern recently and it saved us a lot of dependencies from being injected (see this bit: http://tech.trailmax.info/2013/08/constr.. )

You did mention a test to check if all queries have handlers. Here is my version of tests to check for that issue: http://tech.trailmax.info/2013/12/test-a..
trailmax (URL) - 03 12 13 - 17:04

Hi Steven, I'm in the same case as trailmax, I just found this article (Great job btw).

I Just want to know how do you handle queries like find by id / find by primarykey and findall?
Phil - 03 12 13 - 23:33

Phil, take a look at what trailmax does, I'm doing about the same in my applications. I define a generic "class GetByIdQuery<TEntity> : IQuery<TEntity>" query class.
Steven - 04 12 13 - 11:44

Hi Steven,
I just found this series of articles and it is great, good job.
I have been interrested in CQRS for a while now and I think your articles are a good starting point.

Anyway, I was wondering, do you use any kind of messaging with this architecture in your actual projects (Brokered, Distributed) and if so, do you use any kind of abstraction on top of them ?
Al - 09 12 13 - 15:40

Al, it depends on the project. I just finished a project where we needed to build an application that worked in offline mode, and this meant adding caching decorators for queues and queuing commands for further processing. This was all based on the same IQueryHandler and ICommandHandler abstractions I wrote here on my blog.
Steven - 13 12 13 - 16:39

I think your principles are absolutely correct but in my experience this is in most scenarios over kill and ultimately reduces the amount of time you have to implement robust functionality which is after all what you are being paid for. Personally I have abstracted away like this too but after 15 years of coding I am moving back to less layers, more injection and simpler code. The benefits of infinite indirection and (bloody) Command patterns are minimal (I have never really seen a genuine benefit other than pretty symetries) over just coding the darn thing.

Basically what I find that works best is comprimise (depending on project goals and scale of course) and is vastly simpler:

1. Create 1 or more DataContexts to encapsulate data access, exposing POCO lists and objects directly to services, ui
2. Extend DataContexts with partial class to implement (stored proc simple data access code, include, dont expose IQuery in general but on occasion it can be helpful)
3. Extract interface for each DataContext (e.g IUserRepository) and inject that into Business logic services using IoC (define object full graph at start)
4. Testing is now straight forward, just use Moq to inject results directly into your system by create Moq().Setup(r => r.GetUsers()).Returns(new List())

That structure is simple and has all the benefits of this design but
1. frees developers from having to create endless classes to implement even basic functionality
2. reduces chance of bugs by reducing codebase
3. speeds up onboarding of new developers because its simple
4. easier to maintain and debug
5. easier to inject results with 1 moq class (the IDataContext)
6. did I say less code!!
7. faster build time
8. easier to refactor
9. happier developers

The number of overly engineered systems I am seeing these days is frightening, it seems developers are losing sight of the goals of their system and customer and getting caried away with abstracting abstration to the point that even a method is an IMethod. Its a poor developer who can't see the tradeoffs and where to draw the line, (Command pattern and Event aggregator I am looking at you!), it makes maintenance and further development an absolute nightmare! Oh and forget about handing the code over should you move on to another project or company..

My advice to new developers is to try to reduce the number of layers and indirection not increase them arbitarily like this! As long as with some dependency injection and a decent mocking frameworks you can mock out calls to your db then you are gonna be ok.

Anyway just my immediate thoughts and its a very good articles despite me disagreeing with some of your points!

Good luck
Tom - 28 08 14 - 01:00

@Tom,

I have to agree with you that when applying these abstractions there will be occasions where the logic contained in a class is little more than what would be a single method in a more conventional style development. However, working with these abstractions does pay dividends:

- SOLID principles: solutions built around these patterns promote a flexible and extensible code base, i.e. a SOLID code base
- Aspect Oriented Programming: a simple set of join-points for apply concerns without resorting to reflection and runtime generation (i.e. interception)
- Strategy Pattern: injecting functionality is great example of Inversion of Control

You are right when you imply that this may not be the only way to build an app but I've yet to see a well formed and fully justified argument for not following SOLID principles.
Peter - 08 09 14 - 16:38

@Tom, I find your reasoning about less abstractions, simpler and less code interesting. As a happy adopter of this design I have been questioning myself about the practical and impractical applications of this model. So far, I find it more practical than impractical. Let me elaborate...

At first, the setup may be intimidating, because you have to setup a few abstractions and implementations. But they all serve their purpose. Once setup there is little or no additional configuration needed, except dependencies like a datacontext that would need configuration anyway. After that it's writing commands (data holders) and their handlers (execution logic). All the dependencies are setup so datacontexts (unitofwork) only require inclusion through the constructor.

All that rests afterwards are simple data packages (commands or queries) and their handlers. A good setup (for example MVC) requires no less than a query handler service (i.e. IQueryProcessor) that handles the query (wires the query and handler) and returns the response. The same can be done with commands, but is not preferred.

Here is a real life example of a controller:

public class AccountController : Controller
{
   private readonly IQueryProcessor processor;

   public AccountController(IQueryProcessor processor)
   {
      this.processor = processor;
   }

   public ActionResult Index()
   {
      return this.PartialView();
   }

   public ActionResult GetOverview()
   {
      var accounts = this.processor.Execute(new GetAccountOverviewQuery());

      return this.Json(accounts);
   }

   public ActionResult GetDetails(GetAccountDetailsQuery query)
   {
      var details = this.processor.Execute(query);

      return this.Json(details);
   }
}

Also on the corresponding query and its handler:

public sealed class GetAccountDetailsQuery : IQueryResult
{
public int Id { get; set; }
}


public sealed class GetAccountDetailsQueryHandler
   : IHandleQuery
{
   private readonly IAuthorizedRepository accounts;

   public GetAccountDetailsQueryHandler(IAuthorizedRepository accounts)
   {
      this.accounts = accounts;
   }

   public AccountDetailView Handle(GetAccountDetailsQuery parameters)
   {
      return (
         from account in this.accounts.Authorized()
         where account.Id == parameters.Id
         select account)
         .ToAccountDetailView()
         .Single();
   }
}

Note that this setup is supported with dependency injection, the IAuthorizedRepository<Account> accounts is injected and can also easily be replaced with a mock when testing.

With a correct setup, this would be the only code you’d have to write. How is this over-engineered? The main goal is to separate data and logic with the extent of two interfaces. We have used standalone classes as you suggested, but the lack of generic logging, transaction management and more have pushed us towards this design. With great benefits I must say.

I agree with you that this kind of engineering may induce more and higher abstractions thus possible over-engineering. I also suffer from this syndrome, but it is a discipline you have to master anyway as a developer. There is no excuse for over engineering an application as well as under engineering. It’s a balance that must be found.
Paul - 29 08 14 - 32:32

For more information about applying paging and ordering to queries, please take a look at the following discussion: https://solidservices.codeplex.com/discu..
Steven (URL) - 14 12 14 - 11:41

I'm working on a scheduling project so I defined a ScheduleAmOrderCommand, ScheduleAnOrderCommandHandler that schedule an Order, sometimes user wants to preview Order scheduling details in a gantt chart form(just after an order scheduled or for a before scheduled Order) so I don't know for the Preview I should define a CommandHandler or a QueryHandler?
Masoud - 09 02 15 - 09:30

@Masoud: Queries should be idempotent. That is, if you run the same query twice you should get the same result (unless a command have modified the state in between).

So you could consider queries to be read only, the only fetch the current state, while commands modify it.

Hence if the preview is just to check the state of the scheduling, define a query.
jgauffin (URL) - 09 02 15 - 10:04


No trackbacks:

Trackback link:

Please enable javascript to generate a trackback url


  
Remember personal info?

/

Before sending a comment, you have to answer correctly a simple question everyone knows the answer to. This completely baffles automated spam bots.
 

  (Register your username / Log in)

Notify:
Hide email:

Small print: All html tags except <b> and <i> will be removed from your comment. You can make links by just typing the url or mail-address.