I'm working on implementing a basic CQRS+ES application. I've seen many examples but I don't understand the routing between the command handler and aggregate.
In some examples, the work is did in this way:
XCommandHandler:
void Handle(XCommand command) {
var aggregate = this.repository.Find<Aggregate>(command.aggId);
aggregate.InvokeSomeBusinessLogic(command.property1, command.property2);
this.repository.Save(aggregate);
}
But others do in another way:
XCommandHandler:
void Handle(XCommand command) {
var aggregate = this.repository.Find<Aggregate>(command.aggId);
aggregate.InvokeSomeBusinessLogic(command);
this.repository.Save(aggregate);
}
What is the best approach, especially when you have many properties (15 or more) in a command?
This isn't particularly a question about CQRS+ES, but just about API design overall. As Clean Code explains, a method with no parameters is better than a method with one parameter, which is better than one with two parameters, etc.
Blindly following that rule should always make you select your second option:
aggregate.InvokeSomeBusinessLogic(command);
However, blindly following any rule is rarely a good idea. In this case, it would be a good idea to consider the Interface Segregation Principle as a countering force:
Clients should not be forced to depend on methods they do not use.
Since getters and setters are methods too, I think this principle applies to Command Objects as well.
Thus, if you have 15 or more properties, but the method in question only needs two of them, perhaps it would be better to just pass those two values.
Another thing entirely is that if you have a Command Object with 15 properties, you may want to rethink your design. One of the fundamental assumptions behind CQRS+ES is that applications present task-based UIs, which ensures that each Command (and the corresponding Events) are 'small'.
Editing in Mark's comments with links because one of the links were broken:
Updating aggregate info isn't task-based; it's CRUD. Perhaps these two articles from Udi Dahan will be helpful.
Queries, Patterns, and Search – food for thought
Tasks, Messages, & Transactions – the holy trinity
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With