2

I'm trying to figure out what is the best way to update a polymorphic child entity inside an aggregate root. For reference, let's say I have a ShippingContainer root entity that stores Cargo objects; there are many types of Cargo objects, for example, BigCargo, HazardousCargo, etc., each with their own unique properties.

I was reading this question: Update an entity inside an aggregate

The answer to this question seems to indicate I should place the ChangeCargo method on the ShippingContainer object taking some kind of DTO parameters object. My question is whether or not this is still best practice when the object you are trying to update is polymorphic (do I now need a hierarchy of DTO objects mirroring the Cargo object types?), or should I be doing something else?

Community
  • 1
  • 1
Joshua Barron
  • 1,532
  • 2
  • 26
  • 42
  • 1
    I do have a feeling that the ShippingContainer (SC) is not actually an Aggregate Root but rather a simple holder of a collection of Cargo (i.e a disguised repository) or a criteria for grouping Cargo. Ask yourself if the SC can function without any Cargo, if it has any behavior outside being a list of Cargo or a facade. – MikeSW Jan 26 '13 at 07:28

1 Answers1

2

If the ChangeCargo use case knows the specific type of cargo it wishes to change, then there would likely be specific versions of this method for each cargo type.

If however, the change is itself agnostic of the cargo type, then it would be best to make use of polymorphism and delegate the update to each cargo subtype. The change could be expressed with a DTO, a value object or a few parameters.

For example (C#):

class ShippingContainer
{
    List<Cargo> cargos;

    public void ChangeCargo(string cargoId, DateTime expectedArrival, ...)
    {
        var cargo = this.cargos.FirstOrDefault(cargo => cargo.Id == cargoId);
        cargo.Change(expectedArrival, ...);
    }
}

class BigCargo : Cargo
{
    public void Change(DateTime expectedArrival, ...) { }
}

class HazardousCargo : Cargo
{
    public void Change(DateTime expectedArrival, ...) { }
}

The parameters starting with expectedArrival could be a DTO or whatever best represents the change.

Marcos Dimitrio
  • 6,651
  • 5
  • 38
  • 62
eulerfx
  • 36,769
  • 7
  • 61
  • 83
  • Assuming each kind of cargo needs unique data, do you think I should use a hierarchy of DTOs representing each kind of change (as I suggested in my original question?) – Joshua Barron Jan 25 '13 at 18:41
  • If there is unique data that means that the change use case knows about the specific type of cargo it wishes to change. So you would have a set of distinct DTOs or set of distinct change methods, but the DTOs don't need to form a hierarchy, but they can if there is benefit to resuing something. – eulerfx Jan 25 '13 at 18:45
  • If I have a unique set of DTOs, how can I effectively delegate the change operation (since the aggregate method would need to take a more generic DTO?) – Joshua Barron Jan 25 '13 at 19:10
  • One way is to have ShippingContainer cast Cargo to appropriate type and pass DTO to method on Cargo subtype. Another way is to have DTO hierarchy and have each Cargo subtype cast DTO to required type after ShippingContainer passes DTO to it. – eulerfx Jan 25 '13 at 19:16