Search code examples
domain-driven-designddd-repositoriesaggregateroot

DDD - Aggregate Root holding reference for a domain service


Is it acceptable that my aggregate root holds a reference for a domain service in order to "save itself" while not holding reference to any repository?

The idea behind this is not have a application service with code like myDomainService.UpdateOrAdd(myAggregateRoot) but something like myAggregateRoot.Update()


Solution

  • Is it acceptable that my aggregate root holds a reference for a domain service in order to "save itself" while not holding reference to any repository?

    DDD doesn't really have a standards body, or anything like that, so acceptable is going to be a subjective judgement.

    It is weird, though, and if you were to bring that into a code review, I'd expect a lot of push back, simply because its contrary to the usual conventions.

    The conventional approach is that the aggregate root object is just an entity in the domain model, and therefore the code within the implementation should look like domain code, not infrastructure code. Consequently, the responsibility for saving the state of the aggregate is normally assigned to the repository, rather than the object itself.

    From the point of view of the application, there's very little to distinguish the code you describe, which probably looks something like

    // TradeBook is the root of the aggregate
    TradeBook book = repository.getById(...);
    book.placeOrder(...)
    book.update();
    

    and the more usual spelling

    TradeBook book = repository.getById(...);
    book.placeOrder(...)
    repository.save(book);
    

    So, principle of least surprise; if you follow the usual pattern, the developer who inherits responsibility for your code is going to have an easier time of it.