7

In Eric Evan's book "Domain Driven Design" (which people often call 'the best example for DDD'), there are many examples of aggregate roots (mostly domain models or even entities) that fullfil a certain request.

Let's take the following example:

public Car : IAggregateRoot {

    public List<Wheel> Wheels { get; set; }

    public void ReplaceWheels();

}

In order to replace the wheels, I have to request a new set of wheels from the GarageService, which itself gathers the wheels from the WheelRepository. In one scenario, I don't be a customer, but a garage owner / mechanic who replaces the wheels, so it feels natural to call:

myCar.ReplaceWheels(); 
// I'm a domain expert! I have the capabilities to replace the wheels

My question is: Is it right to inject the WheelService as a dependency of the aggregate root? Or should I better talk only over the WheelService?

public class MyCar : IAggregateRoot {

    private readonly IWheelService _wheelService;

    public List<Wheel> Wheels { get; set; }

    public MyCar(IWheelService wheelService) {
        this._wheelService = wheelService;
    }

    public void ReplaceWheels() {
        this.Wheels = _wheelService.getNewSet();
    }

}

or

myWheelService.getNewSet(Car car);
Acrotygma
  • 2,531
  • 3
  • 27
  • 54
  • 1
    They way you interpret the *Aggregate Root* concept, it looks like an *Entity* (or *Value Object*). If so, it probably shouldn't have dependencies: http://stackoverflow.com/a/4836790/126014 – Mark Seemann Mar 17 '14 at 09:45
  • @MarkSeemann This means entities can never be considered as aggregate roots, only domain services? – Acrotygma Mar 17 '14 at 16:23
  • What makes you conclude that? – Mark Seemann Mar 17 '14 at 17:29
  • Maybe these two answers can help: http://stackoverflow.com/questions/21704465/accessing-a-web-service-from-cqrs/21718752#21718752 and http://stackoverflow.com/questions/22263646/unit-testing-value-objects-in-isolation-from-its-dependencies/22344599#22344599 – Eben Roux Mar 18 '14 at 04:19

1 Answers1

2

Aggregate roots are very likely to have dependencies. For example, if you have an Invoice aggregate root entity, it is likely going to have a LineItem collection. The only way to edit the line items is using the InvoiceRepository.

If the Invoice was not an aggregate root, invoice line items would have their own repository.

Your example looks fine if you never have to work with wheels outside the context of the car. The only question is can the car replace its own wheels? If not, the method is probably located in the wrong place.

Dmitry S.
  • 8,373
  • 2
  • 39
  • 49
  • "The only question is can the car replace its own wheels?" questions like these are the heart of DDD imo, and for whatever reason, the hardest value for developers to embrace. – Sinaesthetic Jan 03 '17 at 00:45