Let's say we have a class Order
(related to user) and it has property state
. I want to prevent having more than one confirmed order in the same time so before I confirm any order I have to check if there is already some confirmed in it's time period.
I can make 2 approaches (I know of):
OrderRepository
has a function changeState
which search for conflicting confirmed orders before changing it and allows it only when nothing is found - the problem here is repository knows about logic of changing state.
OrderRespository
is injected into Order
and Order
has function changeState
which will use that repository to check for conflicts - here problem is the domain object know about persistence.
What is a right way to do?
Repositories are not in charge of domain invariants. Aggregates are. If no Aggregate has the needed info inside itself to check the invariant, try to question your aggregate design and maybe come up with a new one.
You can use a Domain Service, alternatively. As a weaker option, you could also degrade the domain invariant down to a simple use case precondition and have it checked by the Application Service/Command Handler. Note that the latter 2 options don't provide as strong a guarantee that domain entities will be in a consistent state at all times regarding that rule.