Skip to main content

Command/Query Object pattern

July 22, 2014 mgroves 0 Comments
Tags: csharp dapper design patterns

Welcome! This is one of the most popular posts on my blog. Thanks for reading! If you're into podcasts, check out The Cross Cutting Concerns Podcast, with interviews about interesting and fun technology.

I've heard some talk on twitter, blogs, and at various user groups and conferences for a while now about using the command/query object pattern instead of the repository pattern for a data access layer, and all the benefits of doing so.

So, I decided to explore it for myself. I converted over my Ledger project, since it used repositories, has some complexity, but is not particularly large.

Ledger already uses Dapper, so I started with Dustin Brown's post on using command/query with Dapper. For the most part, I followed what he did exactly (I also had to finally get Ledger using an IoC container, which I had been putting off for a while). These are the four files I used to get started with the pattern:

Note that mine differs from Dustin's only in that his IDatabase contains two methods named Execute, whereas mine contains one named Query and one named Execute. Note that except for IDatabase, these all depend on System.Data.IDbConnection (which is what Dapper uses). So, if you want to use a different DB access library, you'll have to change these.

Now, you need to create queries and/or commands. A query returns data, a command manipulates data. Here's a command that uses Dapper to create a new ledger:

Note that the information for the new ledger is passed via a constructor. And here's an example of a query that returns a single ledger, given an ID number (note that the ID is a constructor parameter).

Here's an example of both of those command/query objects in action inside of a controller.

That's the mechanics of it. It was much simpler to code than it might sound.

I don't know if I'm ready to draw any definitive conclusions about this pattern yet, but here are my thoughts:

  • I'm not particulary happy with the ceremony involved when doing this in C#. Compared to repository, it's a bit of extra noise and typing to use Execute + new keyword + constructor parameters + private fields to hold arguments.
  • Organizationally, I don't have to think about which method goes to which repository anymore. Organization, then, is strictly a matter of folders and/or namespace, and changing those is not as costly. I like that.
  • I also like that instead of 2, 3, or even more repositories, I only need one IDatabase member in my controller.
  • I haven't gone hands-on with unit testing, but I don't anticipate it being much harder. I could also forsee that this pattern is less likely to result in broken tests when making changes to a repository's interface.

I am impressed, but I am not entirely convinced yet. I think this may need further research, especially when it comes to unit tests.

Comments

Matthew D. Groves

About the Author

Matthew D. Groves lives in Central Ohio. He works remotely, loves to code, and is a Microsoft MVP.

Latest Comments

Twitter