We're currently exploring CQRS in our future applications. To give a bit of a background, we use a simple CRUD-style service before something like this.
Old Pattern:
- Controller
- Command/Service
- Model
Then the validation logic is inside the model like ValidateSave(SalesOrderModel), ValidateSubmit(SalesOrderModel), ValidateApprove(SalesOrderModel), etc. Since it's validating the SalesOrderModel, it's very easy to reuse a lot of the validation logic and sometimes we straight up do something like this bool ValidateSubmit(SalesOrderModel model) => return ValidateSave(model)
Now that we're in CQRS the layout is something like this:
- Controller
- CommandRequest
- CommandHandler
- Entity/Model <-- POCO auto-generated by ORM
Then the common practice is to validate it against the CommandRequest which in this case will be SaveSalesOrderCommand, SubmitSalesOrderCommand, etc. Now the problem here is they are of different class so I have to separately code each of their validation logic. I find this hard to maintain since I always end up copy pasting my Save Validation to Submit Validation whenever a new validation comes up. Not to mention the other issues that rises up with non-DRY approach.
I can't seem to find any resources online that tackles this problem and I'm starting to think it's acceptable and it's a "me" issue. The validation is just one example, this is also applicable in Handler side where sometimes there are repetitive code in which in our previous pattern, we either do it in the Command or Model (so data to process is already mapped to Model). While here in CQRS, they seem to be vertically sliced to the point that a command request from a same module is completely separate from each other code-wise and file-wise.
My idea to solve this:
Create an interface for the
CommandRequestlikeISalesOrderCommandwhich will be implemented bySaveSalesOrderCommand,SubmitSalesOrderCommand, etc. Then aSalesOrderValidationwhere all validation logic is placed and validates againstSalesOrderCommand. I tried this and it works but I don't really prefer this mostly due to the added complexity and forcing otherCommandRequestto implement fields that they don't really need.Similar to #1 but in this case, the
SalesOrderValidationwould validate against the entitySalesOrder. Then on each validation of theCommandRequest, I will map them to theSalesOrderentity. I like this and a lot simpler that #1. I just don't know if this has negative implications that I'm still not seeing.
Note: For simplicity sake, we don't implement a full-blown DDD design so the entity is just a POCO and not some entity with rich business implementations attached to it.
Thanks!

Save,SubmitandApprovecommand payloads all need to contain the full SalesOrder? Usually, validating a command is rarely the same as validating an entity, as a very limited number of commands should contain the full entity. An alternative is to let the domain layer validate the entity.Approve, yes, it doesn't necessarily need the full details. ForSaveandSubmitit needs the full details since in our scenario, these actions are initiated right after the user encode/edit the form (not yet persisted in db). So a user can edit a form and clickSaveif it's not yet final orSubmitif what they edited is final. Both of these actions would still have to persist the updated record in database and have a high probability of having same validation.