views:

1203

answers:

4

I'm trying to get my head around how to properly use the repository pattern. The central concept of an Aggregate Root keeps coming up. When searching both the web and Stack Overflow for help with what an aggregate root is, I keep finding discussions about them and dead links to pages that are supposed to contain base definitions.

In the context of the repository pattern, what is an aggregate root?

+1  A: 

From a broken link:

Within an Aggregate there is an Aggregate Root. The Aggregate Root is the parent Entity to all other Entities and Value Objects within the Aggregate.

A Repository operates upon an Aggregate Root.

More info can also be found here.

Otávio Décio
Thank you. That is definitely the most common and frustrating broken link I continually ran across.
Dinah
+2  A: 

Imagine you have a Computer entity, this entity also cannot live without its Software entity and Hardware entity. These form the Computer aggregate, the mini-ecosystem for the Computer portion of the domain.

Aggregate Root is the mothership entity inside the aggregate (in our case Computer), it is a common practice to have your repository only work with the entities that are Aggregate Roots, and this entity is responsible for initializing the other entities.

Consider Aggregate Root as an Entry-Point to an Aggregate.

In C# code:

public class Computer : IEntity, IAggregateRoot
{
    public Hardware Hardware { get; set; }
    public Software Software { get; set; }
}

public class Hardware : IEntity { }
public class Software : IValueObject { }

public class Repository<T> : IRepository<T> where T : IAggregateRoot {}

Keep in mind that Hardware would likely be a ValueObject too (do not have identity on its own), consider it as an example only.

F.Aquino
+11  A: 

In the context of the repository pattern, aggregate roots are the only objects your client code loads from the repository.

The repository encapsulates access to child objects - from a caller's perspective it automatically loads them, either at the same time the root is loaded or when they're actually needed (as with lazy loading).

For example, you might have an Order object which encapsulates operations on multiple LineItem objects. Your client code would never load the LineItem objects directly, just the Order that contains them, which would be the aggregate root for that part of your domain.

Jeff Sternal
Hypothetically, if the client code needed the LineItem for some other purpose, would that form a seperate aggregate (assuming there would be other objects involved not related to the Order object)?
Ahmad
@Ahmad, other aggregates might refer to LineItems as read-only data, they just can't *change* them. If other aggregates could change them, you couldn't protect the order's invariants (nor the line items').
Jeff Sternal
Take a look at this eg http://www.lostechies.com/blogs/jimmy_bogard/archive/2010/02/23/strengthening-your-domain-aggregate-construction.aspx . In the example, Customer is an invariant of Order, right? However, Customer can also be the another aggregate root? Or am I missing some fundamental understanding here?
Ahmad
In that example, Customer and Order might both be aggregate roots, but I don't think the author is suggesting you can change Orders via the Customer object (via some method like Customer.RemoveFirstItemFromOpenOrders()) or the reverse (e.g., Order.UpdateCustomerBillingAddress()).
Jeff Sternal
It kinda makes senses to me a bit more now..thanks Jeff
Ahmad
+6  A: 

From Evans DDD:

An AGGREGATE is a cluster of associated objects that we treat as a unit for the purpose of data changes. Each AGGREGATE has a root and a boundary. The boundary defines what is inside the AGGREGATE. The root is a single, specific ENTITY contained in the AGGREGATE.

And:

The root is the only member of the AGGREGATE that outside objects are allowed to hold references to[.]

This means that aggregate roots are the only objects that can be loaded from a repository.

An example is a model containing a Customer entity and an Address entity. We would never access an Address entity directly from the model as it does not make sense without the context of an associated Customer. So we could say that Customer and Address together form an aggregate and that Customer is an aggregate root.

Jason