3.1 KiB
Application Layers
This document describes the three-layer architecture used in each module and the strict dependency rules that must be followed.
Layer Overview
Each module is organized into three distinct layers following Domain-Driven Design principles:
src/Modules/{module-name}/
├── Domain/ # Pure business logic
├── Application/ # Use cases and orchestration
└── Infrastructure/ # External adapters and implementations
Layer Descriptions
Domain Layer
The Domain layer contains the core business logic and is the heart of the module. It includes:
- Entities: Business objects with identity and lifecycle
- Value Objects: Immutable data containers representing concepts
- Repository Interfaces: Contracts for data access (no implementations)
- Domain Services: Business logic that doesn't naturally fit in entities
- Domain Events: Events representing business occurrences
- Exceptions: Domain-specific business rule violations
Key Principle: The Domain layer must be completely independent and have no dependencies on any other layers.
Application Layer
The Application layer orchestrates business processes and coordinates between the domain and infrastructure. It includes:
- Use Cases/Application Services: Specific business scenarios (e.g., FetchAllActivities)
- Application Events: Events related to application processes
- DTOs: Data transfer objects for communication between layers
Dependencies: Can depend on Domain layer and itself only.
Infrastructure Layer
The Infrastructure layer provides concrete implementations, external integrations, and adapters. It includes:
- Repository Implementations: Concrete data access implementations
- API Controllers: HTTP endpoint handlers
- Web Controllers: Web interface handlers
- Command Handlers: Process commands that change state
- Query Handlers: Process queries that retrieve data
- Database Commands/Queries: Specific data operations
- External Service Adapters: Third-party service integrations
- Persistence Models: Database-specific representations
Dependencies: Can depend on Application layer and itself only.
Dependency Rules
Allowed Dependencies
- Domain (no dependencies)
- Application ─── may depend ──→ Domain
- Infrastructure ─── may depend ──→ Application
What This Means
- Domain files cannot import or use anything from Application or Infrastructure
- Application files can import from Application and Domain only
- Infrastructure files can import from Infrastructure and Application only (not Domain directly)
Benefits of This Architecture
- Domain Purity: Business logic remains free from technical concerns
- Testability: Domain can be tested in isolation without infrastructure
- Flexibility: Infrastructure can be swapped without affecting business logic
- Maintainability: Clear separation of concerns makes code easier to understand
- Framework Independence: Domain logic is not coupled to specific frameworks