Sponsor: Using RabbitMQ or Azure Service Bus in your .NET systems? Well, you could just use their SDKs and roll your own serialization, routing, outbox, retries, and telemetry. I mean, seriously, how hard could it be?

Once I started down the path of segregating commands and queries, I soon enough ran into a few issues that I needed to solve.
- Identifying Commands & Events
- Correlating Commands & Events
- Idempotent Commands
- Idempotent Events
If you are familiar with CQRS, then you may have run into these issues as well. If you are not completely familiar with CQRS but have heard of it, to be clear, I’m not talking about Event Sourcing, Domain Driven Design, or having multiple data stores or any of the overly complex version people think it is.
I’m simply talking about splitting up incoming requests into commands and queries.
Starting with CQRS, CQRS is simply the creation of two objects where there was previously only one. The separation occurs based upon whether the methods are a command or a query (the same definition that is used by Meyer in Command and Query Separation, a command is any method that mutates state and a query is any method that returns a value). – Greg Young
Identifying Commands and Events
Since commands are simple objects that can be serialized. I often will log the inbound command if there is a failure in the command handler.
This is really helpful for debugging failed commands as I can view the failed commands and retry them in my development environment for troubleshooting.
But it doesn’t stop there.
If you are emitting Events from your Command Handlers or Domain, it is often helpful to keep track of which Command caused which Event.
In Microsoft’s Patterns & Practices
CQRS Journey, they created an
Envelope<T> to accomplish this.
For a simplified version we can accomplish this with:
If needed, we can now wrap our commands in an Envelope before sending to the mediator.
Correlating Commands & Events
Now since we have wrapped our inbound command in an Envelop that contains a MessageId, in our Handler when emitting events, we can now add the MessageId from the Command to the CorrelationId of the new Event.
Idempotency
Next I’ll look at how I can use the Envelope for creating idempotent commands that do not contain a natural way of doing so.
How about you?
Do you apply a similar pattern as well? I’d love to hear about other implementations or uses. Comment below or on twitter.
Other Posts