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.