Accessing Aggregate Root State from Aggregate Member

Hi,

Question:

  1. Is it possible to access a variable or a state of an Aggregate Root from it’s Aggregate Member?
  2. Is it an anti-pattern in DDD concept for an Aggregate Member to access variable from it’s Aggregate Root?

I am quite new with DDD and Axon framework, through out my work, I found out that I need to access a state in Aggregate Root from an Aggregate Member while handling a command for some validation. I would like to know how to achieve that in Axon.

Scenario:
Aggregate Root

Aggregate
public class CarAggregate {
AggregateIdentifier private String plateNumber;
private String brand;
AggregateMember private List tyres;
}

Aggregate member:

Aggregate
public class TyreAggregate {
EntityId private String tyreId;
CommandHandler
public void handle(ChangeTyreCommand command){
// car brand validation for this command somehow
}
}

Unfortunately, there is no direct reference to root from Aggregate members right now.

Your choices are limited in this case:

  1. Move this command handler to the root aggregate (obviously)
  2. When you create member from the root, pass a reference of the root aggregate, and keep it in member

Example:

Aggregate command handler:

tyres.add(new TypeAggregate(tyreId, this))

Member:

CarAggregate root;
EntityId private String tyreId;

TyreAggregate(String id,  CarAggregate aggregate) {
   tyreId = id;
   root = aggregate;
}

public void handle(ChangeTyreCommand command){
   if(root.someFunction) .{ ... }
}

Hi @stefand,
Thank you so much for your reply.
I have thought about storing the information I need from aggregate root in the aggregate member. But I just wondering tho, is this approach breaking any rule of DDD?
Because now our aggregate member (or entity) needs to always aware of the state of its aggregate root.
What do you think?

That is true, if something depends on root state, than its not in-depended, and should be inside aggregate it depends on… As you saw there are workarounds but creating such dependencies would cause you issues on long term.

What I would do in this cases is to move command handler in root aggregate, which will check the state of root aggregate, if you want to proceed, you get your member entity object and call a member function on it which does some job.

if (state is true) typeEntety.doBusinessLogic(...); //<- doBusinessLogic method is part of TyreAggregate.java file

This way, command handler that does validation is where it should be, in aggregate, but your business logic method is in member, mostly for logical organisation.