Clean Architecture & DDD Mastery

Domain Services: When logic doesn't fit in an entity

1 Views Updated 5/4/2026

Stateless Logic

Sometimes, a business operation involves multiple entities or doesn't naturally belong to any single entity. This is where Domain Services come in.

1. Orchestrating Multi-Aggregate Logic

Imagine a FundsTransferService. It needs to check the balance of Account A and update the balance of Account B. Neither account should own the logic for transferring to another account. The Domain Service acts as a stateless orchestrator within the Core layer.

2. Domain Service vs Application Service

A **Domain Service** contains business logic. An **Application Service** contains coordinate logic (logging, transactions, security). Rule of thumb: If the logic is something a business expert would care about, it's a Domain Service. If it's about technical plumbing, it's an Application Service.

3. Architect Insight

Q: "Should I use Domain Services for everything?"

Architect Answer: "NO! This is a common trap that leads to 'Anemic Domain Models'. Always try to put logic inside your Entities and Value Objects first. Only reach for a Domain Service as a last resort when the logic is truly stateless or involves multi-aggregate coordination. Keep your entities 'fat' and your services 'thin'."

Clean Architecture & DDD Mastery
1. Architectural Patterns
The Evolution of Architecture: Monolith to Clean Onion Architecture: Dependency Inversion at the core Clean Architecture: The 'Screaming' architecture Hexagonal Architecture (Ports and Adapters)
2. Domain-Driven Design (DDD) Foundations
Ubiquitous Language: Aligning code with business Entities vs Value Objects: Managing identity and state Aggregates & Aggregate Roots: Defining consistency boundaries Bounded Contexts: Handling complexity in large domains
3. Advanced DDD Patterns
Domain Services: When logic doesn't fit in an entity Domain Events: Decoupling side effects via events Repositories: Mediating between domain and data Unit of Work: Ensuring atomic transactions
4. Implementing the Clean Layers
The Domain Layer: Zero dependencies, pure C# The Application Layer: Orchestrating use cases The Infrastructure Layer: Bridging to the outside world The Presentation Layer: Decoupling the UI from logic
5. Patterns for Data & Logic
CQRS (Command Query Responsibility Segregation) MediatR: Implementing the Mediator pattern in .NET Specification Pattern: Encapsulating business rules Policy Pattern: Handling complex authorization rules
6. Enterprise Domain Challenges
Handling Persistence Ignorance with EF Core Mapping Layers: AutoMapper vs Manual Mapping Validation Strategies: FluentValidation in the App Layer Error Handling: Result patterns vs Exceptions
7. Testing Clean Architecture
Unit Testing the Domain: Fast and pure Testing Use Cases with Mocks Integration Testing the Infrastructure ArchUnit .NET: Enforcing architectural rules via tests
8. Real-World Case Study
Refactoring a 'Spaghetti' Monolith to Clean Architecture DDD in Action: Modeling a complex Logistics system