Monday, 22 September 2025

Domain-Driven Design (DDD)

1️⃣ What is DDD?

Domain-Driven Design is a way to build software by focusing first on the business domain—the real-world problem you’re solving—before worrying about technology.

  • Domain = the business area (e.g., e-commerce orders, banking, healthcare).

  • Goal: Make the code match the business language and rules so developers and business experts speak the same language.

Think: “Code that reads like the business.”


2️⃣ Core Ideas

🗣️ Ubiquitous Language

  • Use the same terms everywhere—requirements, conversations, and code.

  • Example: If business says “Order must be Shipped,” use Order.Ship() in code, not ProcessData().

📦 Bounded Context

  • Break a large system into smaller contexts, each with its own model and database.

  • Example:

    • Ordering Context (Orders, Payments)

    • Inventory Context (Products, Stock)

🧱 Entities and Value Objects

  • Entity: Has an ID and lifecycle (e.g., Order, Customer).

  • Value Object: Describes something by value, no identity (e.g., Address, Money).

🎯 Aggregates

  • A group of related entities treated as one unit.

  • Has a root (Aggregate Root) that controls changes.

  • Example: Order (root) contains OrderItems.

🛠️ Repositories

  • Interfaces for saving/loading aggregates, hiding database details.

🧩 Domain Services

  • Business logic that doesn’t belong to a single entity.

  • Example: PaymentService to handle payment rules.


3️⃣ DDD Layers in a Typical .NET App

A clean structure often looks like:

src/ ├─ Domain // Entities, Value Objects, Domain Events ├─ Application // Use cases, commands/queries ├─ Infrastructure// EF Core, DB, external services └─ WebAPI // Controllers, DI setup
  • Domain layer has no dependencies on database or UI.

  • Infrastructure implements repository interfaces defined in Domain/Application.


4️⃣ Example in Simple C#

// Value Object public record Money(decimal Amount, string Currency); // Entity / Aggregate Root public class Order { public Guid Id { get; private set; } public List<OrderItem> Items { get; private set; } = new(); public void AddItem(string product, int qty, Money price) { Items.Add(new OrderItem(product, qty, price)); } } public record OrderItem(string Product, int Quantity, Money Price);
  • Notice: no EF Core or UI code here—just pure business logic.


5️⃣ Benefits

  • ✅ Code matches business concepts → easier communication.

  • ✅ Easier to change or extend business rules.

  • ✅ Scales well with complex domains.


6️⃣ When to Use DDD

  • Great for complex business domains with rich rules (banking, insurance, e-commerce).

  • Overkill for very simple CRUD apps.


7️⃣ How to Start

  1. Talk to domain experts → gather key concepts and vocabulary.

  2. Identify bounded contexts and main aggregates.

  3. Create the domain model (entities, value objects).

  4. Implement repositories and services.

  5. Keep the domain layer free of infrastructure code.


🚀 Quick Recap

Domain-Driven Design = business-first software design:

  • Speak a common language.

  • Split into bounded contexts.

  • Model the domain with entities, value objects, and aggregates.

  • Keep business logic independent from databases and UI.

This approach fits naturally with Clean Architecture and .NET (ASP.NET Core + EF Core) to build maintainable, long-term solutions.