Hexagonal Architecture
Hexagonal Architecture (also known as Ports and Adapters) is an architectural pattern that isolates the core business logic from external concerns like databases, messaging systems, and APIs. SpecKit implements this pattern across all microservices to achieve maximum testability and flexibility.Conceptual Overview
Layer Structure
- Domain Layer
- Application Layer
- Infrastructure Layer
- API Layer
Location: Reservation Entity:IRedisLock Port:Key Principle: Domain layer defines WHAT it needs, not HOW it’s implemented.
services/{service}/src/{Service}.Domain/Contents:- Domain entities (business objects)
- Domain ports (interfaces)
- Business rules and validations
Dependency Inversion Principle
The Dependency Rule
The Dependency Rule
Core Principle: Dependencies point INWARD toward the domainWhat This Means:
-
Domain layer has ZERO dependencies
- No references to EF Core, Redis, Kafka, etc.
- Pure business logic
-
Application layer depends only on Domain
- Uses domain entities and ports
- No knowledge of infrastructure implementations
-
Infrastructure layer implements domain/application ports
- Depends on external libraries (Confluent.Kafka, StackExchange.Redis)
- Adapts external systems to domain interfaces
-
API layer orchestrates everything
- Configures dependency injection
- Maps HTTP to application commands/queries
Wiring It All Together
Wiring It All Together
Dependency Injection Configuration:Usage in Program.cs:
Benefits Realized in SpecKit
Testability
Domain logic tested without infrastructure:
Flexibility
Easy to swap implementations:No changes to domain or application code required!
Domain Purity
Business logic free from technical concerns:No:
[Table("reservations")]attributesINotifyPropertyChangedinterfaces- ORM-specific code
Independent Evolution
Change infrastructure without touching domain:
- Migrate from Redis to Memcached
- Switch from Kafka to RabbitMQ
- Replace PostgreSQL with MongoDB
- Add caching layer
Real-World Example: Complete Flow
CreateReservation End-to-End
CreateReservation End-to-End
1. HTTP Request arrives at API layer:2. Endpoint creates command and sends to MediatR:3. MediatR dispatches to handler (Application layer):4. Infrastructure adapters execute:5. Response flows back to client:Key Observation:
- Domain defines
IRedisLockandIKafkaProducerinterfaces - Application uses these interfaces without knowing implementation
- Infrastructure provides concrete implementations
- Dependency injection wires everything together at runtime
Ports vs Adapters Summary
- Ports (Interfaces)
- Adapters (Implementations)
Definition: Interfaces defined by the core (domain/application)SpecKit Ports:
Characteristics:
| Port | Defined In | Purpose |
|---|---|---|
IRedisLock | Domain | Distributed locking abstraction |
IKafkaProducer | Domain | Event publishing abstraction |
IDbInitializer | Domain | Database initialization |
IOrderRepository | Application | Order persistence abstraction |
IReservationValidationService | Application | Reservation validation |
- Defined by what the core needs
- No implementation details
- Stable (change infrequently)
Common Pitfalls & Solutions
Related Concepts
CQRS Pattern
See how commands and queries fit within hexagonal architecture
Microservices Design
Learn how each service implements hexagonal architecture
Event-Driven Architecture
Understand Kafka integration via ports and adapters
System Architecture
View complete architecture overview
