What Are Aggregates in Domain-Driven Design (DDD)?
What Are Aggregates in Domain-Driven Design (DDD)?
Have you ever wondered how to keep your business rules safe when multiple objects work together?
In this blog, we'll learn what Aggregates are in Domain-Driven Design, why they are important, and we'll use a simple online shopping example to make everything crystal clear.
Let's get started!
What is an Aggregate?
An Aggregate is a group of related objects that should be treated as a single unit.
Think of it as a boundary around objects that need to stay consistent together.
Inside an Aggregate, there can be:
Entities
Value Objects
And one special entity called the Aggregate Root.
The Aggregate Root controls access to everything inside the Aggregate.
Simple Real-Life Example
Imagine you're placing an order on an e-commerce website.
An order contains:
Order information
Order items
Shipping address
Visually, it looks like this:
Order
Order Items
Shipping Address
In DDD, all of these can form a single Aggregate.
The Order becomes the Aggregate Root.
Why Do We Need an Aggregate?
Let's say an order should never have a negative quantity.
Without an Aggregate, someone could directly modify an order item and accidentally break the business rule.
For example:
Quantity = -5
That doesn't make sense.
Instead, all changes must go through the Order Aggregate Root.
For example:
AddItem()
RemoveItem()
ChangeQuantity()
The Order validates the rules before making changes.
This keeps the data consistent.
Aggregate Root
The Aggregate Root is the entry point to the Aggregate.
External code should only interact with the Aggregate Root.
For example:
Order.AddItem(ProductId, Quantity)
Good!
But this is not allowed:
OrderItem.Quantity = -5
Bad!
The Aggregate Root protects the internal objects and ensures business rules are followed.
Example in C#
Let's look at a simple example.
public class Order
{
private readonly List<OrderItem> _items = new();
public void AddItem(string productName, int quantity)
{
if(quantity <= 0)
throw new Exception("Quantity must be greater than zero");
_items.Add(new OrderItem(productName, quantity));
}
}
Notice that OrderItem is added only through the Order.
The Order controls the business rules.
That's exactly what an Aggregate Root does.
Another Easy Example: Bank Account
Imagine a bank account.
A bank account contains:
Account information
Transactions
Balance
The BankAccount becomes the Aggregate Root.
Instead of doing this:
Balance = Balance - 100
We do this:
Withdraw(100)
Or:
Deposit(100)
The BankAccount validates whether the withdrawal is allowed and keeps everything consistent.
Aggregate Boundary
An Aggregate defines a boundary.
Everything inside the boundary must remain consistent.
For example:
Order Aggregate
Order
Order Items
Customer Aggregate
Customer
Address
These are separate Aggregates.
An Order should not directly modify a Customer.
Instead, it stores only the Customer ID.
This keeps Aggregates small and manageable.
Common Beginner Mistake
Many developers create huge Aggregates.
For example:
Customer
Orders
Payments
Reviews
Notifications
Addresses
This becomes difficult to maintain and can hurt performance.
A better approach is:
Customer Aggregate
Order Aggregate
Payment Aggregate
Review Aggregate
Each Aggregate has a clear responsibility.
How to Identify an Aggregate?
Ask yourself three questions:
Which objects must stay consistent together?
Which business rules must always be protected?
Which objects should be updated in a single transaction?
The answers usually reveal your Aggregate boundaries.
Conclusion
Let's quickly recap.
An Aggregate is a group of related objects treated as a single unit.
An Aggregate Root is the main entry point that controls access.
Aggregates protect business rules and maintain consistency.
In our example:
Order is the Aggregate Root.
Order Items and Shipping Address belong to the Order Aggregate.
All changes happen through the Order.
That's the key idea behind Aggregates in Domain-Driven Design.
If you found this video helpful, don't forget to like, share, and subscribe for more ASP.NET Core and Domain-Driven Design tutorials.

Comments
Post a Comment