A Modular Hexagonal-Clean Hybrid Architecture template built with .NET 9, designed for scalable, maintainable, and plug-in-style backend systems.
Modern applications require flexibility, feature modularity, and clear separation of concerns. This template combines:
- Hexagonal Architecture for inbound/outbound decoupling
- Clean Architecture for layer separation and testability
- Plugin-based modularity for scalable and independently evolvable features
Ideal for: Domain-rich enterprise apps, modular monoliths, service-oriented backends.
This architecture blends concepts from Hexagonal Architecture, Clean Architecture, and Plugin-based Modular Monoliths, with the following principles:
-
Feature-Oriented Modules
Each domain feature (e.g.,User,Auth) is built as an independent module containing its own:- Domain Layer
- Application Layer
- Infrastructure Layer
-
Adapters as Boundaries
Instead of treatinginterfaceas the sole boundary, this pattern treats entire adapter modules as the boundary units, following Hexagonal principles. These modules exposeRegister()methods to inject themselves at runtime. -
Dynamic Adapter Registration
A lightweight plugin mechanism loads all adapters implementingIAdapterModulefrom their assemblies at runtime, allowing high modularity and minimal API-core coupling. -
Decentralized Port Interfaces
Unlike traditional Hexagonal where allportsare defined in a centralCore, this pattern allows each adapter to define its own ports/interfaces to avoid high coupling and make module ownership clearer.
Each module follows the Clean Architecture layering within itself:
[ Api ]
↓
[ Adapter Module ]
├── Application
├── Domain
└── Infra
↓
[ External Dependency ]Core remains free of direct adapter dependencies.
Examples of pluggable modules:
HexaCleanHybArch.Template.Adapters.User– Handles user profile logicHexaCleanHybArch.Template.Adapters.Auth– Handles authentication & token flow
Each implements IAdapterModule, and is auto-registered via AdapterModuleLoader.
To start your own project based on this template:
dotnet new install .
dotnet new hexa-clean -n {new_project_name}Using the DockerFile:
## Build image
docker build -t {image_name} .
## Run Docker file(http: 8080 -> 8081; https: 8081 ->8082)
docker run -d -p 8081:8080 -p 8082:8081 --name {container_name} {image_name}Or using Docker Compose:
# For SQLite (default)
docker-compose -f docker-compose.sqlite.yml up --build
# For PostgreSQL
docker-compose -f docker-compose.postgres.yml up --build
# For MSSQL
docker-compose -f docker-compose.mssql.yml up --buildThis project separates test types clearly:
-
tests/Unit/
Unit tests focused on Core logic and internal rules e.g., UserServiceTests.cs, AuthServiceTest.cs
-
tests/Integration/
API-level tests validating end-to-end flow e.g., AuthApiIntegrationTests.cs, SharedApiFactoryCollection.cs
Test Tools Used:
- xUnit
- Moq
- FluentAssertions
- Microsoft.AspNetCore.Mvc.Testing
See: Integration tests in ASP.NET Core
- .NET 9 SDK
- Docker (required for database containers)
src/
├── Api // Entry API + Middleware
├── Core // Core business logic
├── Adapters/
│ ├── Auth // Auth module
│ └── User // User module
├── Config // Database / DI factory
├── Shared // Common exceptions, DTOs
tests/
├── Unit/ // Pure unit tests
└── Integration/ // API-level testsThe following diagram illustrates the modular, adapter-boundary-centric architecture you're implementing:
📎 Download Architecture Diagram (PNG)
- Each Adapter module contains its own Clean Architecture layers (Application / Domain / Infra)
- The API project composes multiple adapters via their
IAdapterModuleimplementations - The adapter boundary acts as the external interface to the Core
- The Core knows nothing about the Adapters — only ports/interfaces as abstractions
This encourages strong modularity, dynamic plug-in style composition, and separation of concerns per feature.
- Author - Da-Wei Lin
- Website - David Weblog
- MIT LICENSE
- ✅ MediatR integration
- ✅ FluentValidation auto-loading
- ⏳ Swagger modular plugin support
- ⏳ gRPC and EventBus adapters