My domain aggregate is struggling with simple business logic so I feel like I have modeled it incorrectly.
The architecture I have right now uses domain driven design with event sourcing. The domain aggregate produces events which get digested by subscribers. Eventually the event queue will be empty and the view store completely updated.
Where it struggles is with large collections of objects on the aggregate and the need to coordinate between domains.
So one aggregate is a ChatAggregate which allows people to add comments. However a user can only add one comment per hour or one comment for the entire life time. My domain object cannot keep all comments in memory but I still need my ChatAggregate to apply this business logic. Because of the eventually consistent nature of my view store, I cannot let my aggregates query it for business logic. How does DDD handle when an aggregate needs access to a lot of data?
The second issue I have is when a domain command is being processed, I want to query other aggregates before processing the command with the target aggregate. An example is before creating a new ChatCommentAggregate instance, I would like to query the ChatAggregate to see if the chat is still open.
Best Answer
If eventual consistency will not do then you'll need a way to store 100% consistent data on the transactional/write/domain side of things.
That being said, it is sometimes possible to implement a business rule slightly differently but still get the same result. For instance, you could add a list of
ChatAggregateComment
value objects to yourChatAggregate
that store, say, theUserId
,CommentId
, andDateCommented
. This list would grow only as big as the number of people involved in the chat. However, if even that is going to be too large then you could denormalize the data and store this same list as immediately consistent on your write side and then query table through some domain-side query interface.As far as creating a new
ChatCommentAggregate
is concerned you could use yourChatAggregate
as the factory for aChatCommentAggregate
. Your rule could be applied within theChatAggregate.CreateComment
method.