Interface IAggregate
- Namespace
- FunctionalDdd
- Assembly
- FunctionalDdd.DomainDrivenDesign.dll
Defines the contract for an aggregate root in Domain-Driven Design. An aggregate is a cluster of domain objects that can be treated as a single unit for data changes.
public interface IAggregate : IChangeTracking
- Inherited Members
- Extension Methods
Examples
public class Order : Aggregate<OrderId>
{
private readonly List<OrderLine> _lines = [];
public Result<Order> AddLine(ProductId productId, int quantity)
{
// Business logic here
DomainEvents.Add(new OrderLineAddedEvent(Id, productId, quantity));
return this;
}
}
Remarks
Aggregates are the primary building blocks of domain models in DDD. Key characteristics:
- Aggregate roots are the only entry point for modifications to the aggregate
- Ensures all business rules and invariants within the aggregate boundary are maintained
- Tracks domain events that occur during state changes
- External objects can only hold references to the aggregate root, not internal entities
This interface combines change tracking (from IChangeTracking) with domain event management.
Methods
UncommittedEvents()
Gets all domain events that have been raised but not yet marked as committed.
IReadOnlyList<IDomainEvent> UncommittedEvents()
Returns
- IReadOnlyList<IDomainEvent>
A read-only list of domain events that occurred during state changes since the last call to AcceptChanges(). Returns an empty list if no uncommitted events exist.
Remarks
Domain events represent significant state changes that have occurred within the aggregate. These events should be:
- Published to an event bus or message broker after successful persistence
- Used to trigger side effects or update read models
- Cleared by calling AcceptChanges() after successful processing
Typical workflow:
// 1. Execute domain operation
var result = order.Submit();
// 2. Save aggregate to repository
await repository.SaveAsync(order);
// 3. Publish uncommitted events
foreach (var evt in order.UncommittedEvents())
{
await eventBus.PublishAsync(evt);
}
// 4. Mark changes as committed
order.AcceptChanges();