Table of Contents

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();