Search code examples
domain-driven-designddd-repositories

Injecting repositories to domain objects or repositories should be aware of business logic?


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):

  1. 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.

  2. 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?


Solution

  • 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.