Domain-Driven Design in .NET

Domain-Driven Design principles and implementation patterns for building maintainable enterprise applications

Core Philosophy #

DDD focuses on modeling complex business domains through collaboration between domain experts and developers.

Key Building Blocks #

Value Objects #

 1public record Money(decimal Amount, string Currency)
 2{
 3    public static Money operator +(Money left, Money right)
 4    {
 5        if (left.Currency != right.Currency)
 6            throw new InvalidOperationException("Cannot add different currencies");
 7        
 8        return new Money(left.Amount + right.Amount, left.Currency);
 9    }
10}

Entities #

 1public class BankAccount : Entity<Guid>
 2{
 3    private Money _balance;
 4    
 5    public string AccountNumber { get; private set; }
 6    public Money Balance => _balance;
 7    
 8    public void Deposit(Money amount)
 9    {
10        // Business rules
11        _balance += amount;
12        RaiseEvent(new MoneyDeposited(Id, amount));
13    }
14}

Aggregates #

 1public class Order : AggregateRoot<Guid>
 2{
 3    private readonly List<OrderLine> _lines = new();
 4    
 5    public void AddLine(Product product, int quantity)
 6    {
 7        // Invariant protection
 8        var line = new OrderLine(product, quantity);
 9        _lines.Add(line);
10    }
11}

Strategic Patterns #

  • Bounded Context: Clear boundaries between different domain models
  • Ubiquitous Language: Shared vocabulary between technical and domain experts
  • Context Maps: Relationships between bounded contexts

Perfect foundation for Event Sourcing implementations and CQRS architectures.