In a previous post, I laid out an incredibly simple implementation of the command part of cqrs. I specifically left out any comments, so consider this the planned addendum to that post.
Why a code sample/example and why now?
As a general rule, on my blog, I tend to explicitly refrain from posting code. Why?
It varies from day to day, but I tend to read between 50-100 blog posts a day (note to self: there’s a reason why you don’t get enough done in a day. Address.). Among the bloggers I read daily include Ayende. Now, as I have mentioned before, my ego is large enough to be seen from space. Regardless of that, it is no threat to my ego to recognize that I will never be as good as a developer (however that might be determined) as Ayende. I think I’m pretty good, but I have, at least once, had to email him when he posts a code challenge to tell me which user comment had the right solution, because, well, the dude’s really good, and I don’t always get which one is correct.
If I dropped everything and decided to become as good a developer as Ayende (however that might be determined)….yeah, it’s still not going to happen. I accept my limitations here.
Everyone who’s a developer (and I’m willing to bet Ayende has done it at least once) has faced a challenge with some programming task, and gone on-line and searched Google (sorry Bing, love your commercials though). I don’t do it everyday, or even every week, but I bet I have done this at least once a month (on average) since….1998? Did Google exist back then?
If you post code, there’s the chance that someone will Google your code before you die, and then ask why their kitten died because you didn’t foresee some random case that has almost no relation to what you were posting. That’s your problem, protect your kittens.
The single reason why I posted this particular sample is because after reviewing every sample CQRS framework that I could find, they didn’t include one thing I wanted to do.
I didn’t include every single part of the implementation. Why?
I didn’t include implementations of the commands or the handlers or the simple SqlCommandStore. Why?
Nothing in those pieces are remotely interesting. And laziness.
I have ICommand<TReturnValue> but it is never used. Why?
I haven’t determined to my 100% satisfaction what should be responsible for determining if a command should have a return value. Is it the command itself, or the command handler?
I spent a considerable amount of time having the command be responsible. Problem is, I could never get it to work to my satisfaction. Combine the rational explanation that it is properly the responsibility of the handler with the fact that it works, and there you go. But, I left it in to highlight the fact that this is a concern and I’m willing to change my mind.
Also, see above about why I don’t normally post code examples.
Everybody knows commands shouldn’t have a return value. Isn’t this a mistake?
Technically, it is the command handlers that can have a return value, and the command bus that allows it. Whatever. I assume the reader can figure it out.
Okay, this is the main reason why I posted the code. There are multiple reasons why I did this, which intersect in various ways, and so as such, are hard to describe in a linear fashion. I could explain it through interpretive dance, but no one wants to see that. So, let me try.
The typical way (from what I’ve seen, anyway) in which CQRS is implemented involves creating queries that always have a return value and creating commands that never have a return value.
As a result of having commands that have no return value, you need to figure out how to figure out if a command is successful. This is complicated. There are many ways to do this, none of them that I find satisfactory at the moment for the applications that I deal with. Additionally, this is a requirement that usually isn’t required for the applications that I deal with. I don’t want to commit to a requirement I don’t need unless I need to. If I ever do need to commit to that requirement, I can strip out of the interface that commands can have a return value and then refactor accordingly.
Additionally, Derick Bailey had a post about Request/Reply that made a lot of sense to me (the careful reader will note what I said above about using Google). I wanted that functionality in my code. However, Request/Reply is ambiguous when it comes to ‘strict’ CQRS. Is it a command or a query that wants a reply? Obviously a query does, but if your code says ‘Request/Reply’, it might not be obvious that it is a query. So, why not just make it explicit that when you have a command that you want a return value, that’s exactly what it is?
So, that’s what I did. I made it explicit. A command still tells the system that it wants to change something (as opposed to a query, which tells the system you only want to return data), it additionally requests that it gets a reply with whatever it needs.
It isn’t CQRS if you do that
Okay. I’m fine with that.
Everyone knows that while an event bus might publish, a command bus sends. Isn’t this a mistake?
Though I haven’t implemented the functionality behind this semantic difference, no, it isn’t a mistake.
Since I am implementing a command store, this means that I might have a generic command handler that handles all commands (in order to add them to the command store, for instance) and then the specific handler that ‘fulfills the request’ of the command (which will normally produce the events that result from it, etc.).
You wouldn’t want to allow anything to subscribe to a command as if it were an event. That would be a mistake.
I don’t think so.