views:

47

answers:

1

While searching the web, I came across a list of rules from Eric Evans' book that should be enforced for aggregates:

  1. The root Entity has global identity and is ultimately responsible for checking invariants
  2. Root Entities have global identity. Entities inside the boundary have local identity, unique only within the Aggregate.
  3. Nothing outside the Aggregate boundary can hold a reference to anything inside, except to the root Entity. The root Entity can hand references to the internal Entities to other objects, but they can only use them transiently (within a single method or block).
  4. Only Aggregate Roots can be obtained directly with database queries. Everything else must be done through traversal.
  5. Objects within the Aggregate can hold references to other Aggregate roots.
  6. A delete operation must remove everything within the Aggregate boundary all at once
  7. When a change to any object within the Aggregate boundary is committed, all invariants of the whole Aggregate must be satisfied.

This all seems fine in theory, but I don't see how these rules would be enforced in the real world.

Take rule 3 for example. Once the root entity has given an exteral object a reference to an internal entity, what's to keep that external object from holding on to the reference beyond the single method or block?

(If the enforcement of this is platform-specific, I would be interested in knowing how this would be enforced within a C#/.NET/NHibernate environment.)

A: 

My favourite way of enforcing DDD patterns and practices is constantly educating people about their value. There are however moments when I with I had a more rigorous tool.

I haven't done this myself yet, but is seems to me that FluentNHibernate could be a good tool for enforcing aggregate properties.

Your example could be implemented by marking all aggregate roots with 'IAggregateRoot' marker interface and non-root entities with 'IEntity' marker interface. Then, your custom FNH convention would check for entities marked as IEntity referencing entities IEntity and when found, would signal an error (throw an exception for example).

Does it make any sense?

Szymon Pobiega
Marking aggregate root entities with IAggregateRoot and other entities with IEntity could be helpful to control which entities can be used with the repository pattern, but I'm not sure that this would be effective in enforcing good practices in this situation for two reasons.1) Aggregated entities are allowed to hold references to other objects outside the aggregate boundaries (just not the other way around). This would then be a valid use of an IEntity referencing an IEntity.2) If different entities are used as aggregate roots in different use cases, enforcement might not be accurate.
MylesRip
It seems, then, that "enforcing the rules" for aggregate roots is less a matter of defining entities in such a way that the rules **must** be followed, and more a matter of education and eternal vigilance. Would that be a fair statement?
MylesRip