Passing CQRS Commands Directly to Domain Objects

~ TL; DR: I am implementing a CQRS + DDD solution for one of my larger projects, and I am wondering if there is any real reason why my command handlers cannot directly send command objects to my aggregates, in a small number of cases when the command object is data rich? I cannot find any specific reason why this would be some kind of anti-pattern, and I can not find any comments that describe this type of design in detail.

Reference Information. I already implemented CQRS systems, and I applied DDD applications, but never CQRS + DDD in the correct application based on Eric Evans style. Therefore, I ask because I do not want to abuse my Aggregates and harm my application in the long run.

An example of my command object that has enough data bits is a registration command that accepts 8 + fields (first name, last name, preferred name, dob, name, username, password, department, etc.). This is very inconvenient, creating my aggregate method, which has 8 parameters, and an alternative solution to using some kind of dto and having my dto command map handler — either automatically using automapper or inline — seems unnecessary and adding an abstraction without a value.

I can also see future use cases where teams may be rich in data (this will not be a large percentage of teams, but there will still be few of them), so I would like to get this seemingly trivial aspect right from the beginning.

+7
domain-driven-design cqrs
source share
2 answers

Command objects are usually expressed in primitive types, while aggregate method signatures will be expressed in domain concepts.

The fact that you did not immediately find out, which probably means that you missed a lot of opportunities to make explicit concepts explicit in your domain.

"registration team that accepts 8 + fields (first name, last name, preferred name, dob, name, username, password, department, etc.)

What should amaze you is that firstname and lastname can definitely form a meaningful whole, like new FullName(firstname, lastname) , and I'm sure there are many other cases where value objects (VOs) can or should be used in your domain ... Username , Password , etc.? Using VO to simulate things that change together better describes your model, and also reduces the number of arguments you have to go through.

Therefore, this makes the object commands white candidates as aggregated arguments to the method. If you go down this road, you will definitely miss the modeling opportunities.

+10
source share

Agree with @plalx.

Take commands as arguments to the aggregated method, which can lead to too many display codes inside aggregates: mapping primitive types to domain objects that are best placed outside of domain objects.

But for simpler projects, I think this is a good starter.

In the case of registration, a limited context is usually a support domain, and complexity usually arises due to external integration (email notification, registration in social accounts, etc.). In this case, I believe that limited context integration is more important than models inside. Therefore, accepting commands as arguments to an aggregated method can be a quick start to achieve results and save your time in order to focus on your main domain.

+2
source share

All Articles