Introduction
DDD and CQRS have a steep learning curve. There are many articles and code samples that explain the basics of CQRS architecture in a simplified manner. However, when it comes to applying CQRS to a real world application (for example: with using Enterprise Service bus like Azure Servicebus, RabbitMQ or MSMQ), many implementations couple these messaging concerns with core domain. This makes applying CQRS to the real world application difficult.
This series of articles show "how" to achieve architecture with decoupled infrastructure concerns so that the end solution is simple to follow and maintain.
Prerequisites
- Knowledge of DDD
- Basic understanding of CQRS architecture
- Azure Web and Worker Roles
- Azure service bus
Background
DDD emphasizes the need to keep the domain model free of infrastructure and application layer concerns. As depicted in the figure below:
As shown above, the dependencies point inward towards Domain layer. No Layer depends on infrastructure's concrete implementation. Main can be used to bootstrap the dependencies which will be called upon by the Presentation layer.
In DDD, communication across aggregates is done via messaging. In CQRS, messaging is required for sending commands and publishing Events. Thus, messaging becomes a key Infrastructure component when implementing such an architecture.
However, messaging is still an infrastructure component and thus should be abstracted out from the domain. We will create an interface IServicebus
for the same and see how different Servicebus frameworks like Masstransit, nServicebus (with different transports like msmq, Azure servicebus) can be used as concrete implementation of the same in the infrastructure layer.
public interface IServiceBus : IDisposable
{
void Publish(IEvent eventMessage);
void Send(ICommand commandMessage);
}
Thus, all of the layers (except Infrastructure) will work with IServiceBus
interface and will not have direct code dependency on concrete implementation in Infrastructure messaging component. This makes swapping the third party libraries easy with some other implementation and also it does not get into our way when implementing our business logic.
What Will Be Covered in This Series?
Here is a brief introduction to articles in this series.
- Introduction
- Current article explaining the principles being followed.
- Need for Enterprise Servicebus Frameworks and Decoupled messaging with their samples
- We will look at samples from
MassTransit
and nServicebus
documentation and will decouple publish subscribe from those samples.
- Inventory Manager
- CQRS application (with decoupled messaging) - Commands
- Inventory Manager application will be introduced. It is implementation of Greg Young's Simple CQRS Example, however making it usable for real world. Currently Inventory Manager application implements only first usecase of creating an inventory item.
- The post will focus on sending command following CQRS architecture in Inventory Manager
application.
- Inventory Manager
- CQRS application (with decoupled messaging) - Aggregate and Event Sourcing
- Explaining the workings of Aggregate and Event Sourcing in Inventory Manager application
- Focuses on how to ensure publishing of events upon saving of aggregate (without Distributed Transaction)
- Inventory Manager
- CQRS application (with decoupled messaging) - ReadSide
- Thin Read layer in Inventory Manager and points of interest about implementing it