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 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 abstraction :-). 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 View 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. Having a lot of small / focused classes (with clear names) is a good thing, but in this scenario, it might create some overhead, since every query handler would have a constructor that takes some dependencies and stores them in local variables (like I said, C# is a very verbose for doing constructor injection, but it's currently still the best language we've got).

There are ways to remove that overhead (besides using the T4 template I described before), you can for example merge multiple query handlers into a single class:

public class UserQueryHandlers :
IQueryHandler<FindUsersBySearchTextQuery, User[]>,
IQueryHandler<GetUsersByRolesQuery, User[]>,
IQueryHandler<GetHighUsageUsersQuery, UserInfo[]>
{
private readonly NorthwindUnitOfWork db;

public UserQueryHandlers(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();
}

public User[] Handle(GetUsersByRolesQuery query)
{
// Query here
}

public UserInfo[] Handle(GetHighUsageUsersQuery query)
{
// Query here
}

// More methods here.
}

Although the UserQueryHandlers class resembles the initial design we are trying to prevent, there is one crucial difference:  it implements IQueryHandler<TQuery, TResult> multiple times, once per query. This allows us to register this class multiple times, once per implemented interface. Although this class violates the SRP, it gives us all the previously described advantages and doesn't violate OCP or ISP.

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 the Simple Injector, the registration looks like this:

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

This code saves is from having to change the DI configuration each 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 IServiceProvider provider;
private readonly IQueryHandler<TQuery, TResult> decorated;

[DebuggerStepThrough]
public ValidationQueryHandlerDecorator(Container container,
IQueryHandler<TQuery, TResult> decorated)
{
this.provider = container;
this.decorated = decorated;
}

[DebuggerStepThrough]
public TResult Handle(TQuery query)
{
var validationContext = new ValidationContext(query, this.provider, null);

Validator.ValidateObject(query, validationContext);

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 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 - 20 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.

20 comments:

This article violates SRP/ISP - too much information in one place :)
But anyway, very useful.
Evaldas Dauksevičius - 23 12 11 - 13:54

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: http://www.cuttingedge.it/blogs/steven/p.. 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 (http://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,
Is it possible to set up query handlers to return a list of objects instead of an array?
Manu - 26 08 13 - 02:11

@Manu, of course it is. That's just a matter of implementing something like IQuery<IEnumerable<User>> and IQueryHandler<MyQuery, IEnumerable<User>>. No strings attached.
Steven (URL) - 26 08 13 - 10:02

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 massing 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


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.