? Clean architecture is about boundaries, not files!!!
Status: ?? Implementation Guide
Repository: https://github.com/dariemcarlosdev/CleanArchitecture.ApiTemplate (Branch: Dev)
Current State: Single-Project Monolithic with Clean Architecture Foundations
.NET Version: 8.0
Last Updated: January 2025
- Overview
- Why Clean Architecture?
- Current Project Status
- Architecture Principles
- Documentation Structure
- Dependency Flow
- Layer Responsibilities
- Single-Project Implementation
- Multi-Project Solution Layout
- Implementation Guidance
- Best Practices
- Resources
This guide explains how CleanArchitecture.ApiTemplate implements Clean Architecture principles within a single-project monolithic structure. This approach provides the benefits of clear architectural organization while maintaining the speed and simplicity of single-project development.
What is Clean Architecture?
Clean Architecture is a design philosophy that organizes code into layers with clear responsibilities, where:
- ? Business logic is independent of frameworks and databases
- ? Dependencies flow inward to core business rules
- ? High-level modules don't depend on low-level modules (both depend on abstractions)
- ? The system is testable without external dependencies
- ? Technology is pluggable - swap frameworks without rewriting business logic
? Without Clean Architecture:
- Difficult to test business logic without entire framework
- Tightly coupled to specific database or API frameworks
- Hard to understand code flow and dependencies
- Difficult for team members to contribute effectively
- Technology changes become expensive rewrites
? With Clean Architecture:
- Testable business logic in complete isolation
- Framework-agnostic business rules
- Clear code organization and flow
- Team members understand structure immediately
- Easy to swap technologies (EF Core ? Dapper, Azure ? AWS)
Your project already has strong foundations:
- ? CQRS with MediatR (command/query separation)
- ? Pipeline behaviors (cross-cutting concerns)
- ? Dependency injection (loose coupling)
- ? Result pattern (consistent error handling)
- ? Service-based architecture (separation of concerns)
- ✅ Domain Layer Implementation - 85% Complete ??
Clean Architecture takes these to the next level by formalizing layer boundaries and adding structure.
CleanArchitecture.ApiTemplate has a solid foundation with excellent architectural patterns in place:
? CQRS with MediatR - Separation of commands and queries
✅ Dependency Injection - Proper DI setup throughout
? Pipeline Behaviors - Cross-cutting concerns handled elegantly
✅ Result Pattern - Clean error handling and responses
? Clear Separation of Concerns - Well-organized folders
✅ Domain Layer - 85% complete with entities, value objects, and enums ??
Current Architecture:
CleanArchitecture.ApiTemplate/ (Single Project)
+-- Core/
� +-- Domain/ ? 85% Complete
� � +-- Entities/ ? BaseEntity, User, Token, ApiDataItem
� � +-- ValueObjects/ ? Email, Role
� � +-- Enums/ ? UserStatus, TokenStatus, TokenType, DataStatus
� � +-- Exceptions/ ? DomainException, EntityNotFoundException
� +-- Application/ ? CQRS with MediatR
+-- Infrastructure/ ? Services, caching, API integration
+-- Presentation/ ? Controllers, API endpoints
+-- Components/ ? Blazor UI
| Component Type | Status | Count | Description |
|---|---|---|---|
| Base Classes | ? 100% | 3 files | BaseEntity, ValueObject, DomainException |
| Domain Enums | ? 100% | 4 files | UserStatus, TokenStatus, TokenType, DataStatus |
| Value Objects | ? 100% | 2 files | Email, Role |
| Domain Entities | ? 100% | 3 files | User, Token, ApiDataItem |
Total: 12 domain files created with ~3,250 lines of code and comprehensive documentation
| Task | Priority | Estimated Effort |
|---|---|---|
| EF Core Configurations | ?? High | 2-3 hours |
| Unit Tests | ?? High | 6-8 hours |
| Application Layer Integration | ?? Medium | 4-6 hours |
| Repository Pattern | ?? Low | 2-3 hours |
Progress Visualization:
Domain Layer: [��������������������] 85%
? Infrastructure: [��������������������] 100%
? Enums: [��������������������] 100%
? Value Objects: [��������������������] 100%
? Entities: [��������������������] 100%
? EF Configurations: [��������������������] 0%
? Unit Tests: [��������������������] 0%
? Integration: [��������������������] 0%
Key Achievement: All domain entities now follow DDD principles with:
- Factory methods for creation
- Business rule enforcement
- Rich domain behavior (not anemic models)
- Comprehensive validation
- Complete XML documentation
| Challenge | Solution |
|---|---|
| Single Project | Folder organization + naming conventions |
| Layer Boundaries | Interface abstractions + documentation |
| Testing | Separate test projects with mocking |
| Domain Integration | Create EF Core configurations (next step) |
All Clean Architecture documentation is in docs/CleanArchitecture/ directory.
-
01-Domain-Layer.md - 85% Complete
- ? Entities: BaseEntity, User, Token, ApiDataItem
- ? Value Objects: Email, Role
- ? Enums: UserStatus, TokenStatus, TokenType, DataStatus
- ? Business rules and domain logic
- ? EF Core configurations (pending)
- ? Unit tests (pending)
-
- CQRS with MediatR
- Query and Command handlers
- Pipeline behaviors (Caching, Validation, Logging)
- Interface abstractions
- Examples: GetApiDataQuery, LoginUserCommand
-
- EF Core database context and migrations
- API integration services
- Caching implementations
- Email and background services
-
04-Infrastructure-Azure-Layer.md
- Azure Key Vault integration
- Blob Storage service
- Service Bus messaging
- Application Insights
-
- Blazor Server components
- REST API controllers with versioning
- Custom middleware
- Configuration and DI setup
-
- Unit tests for Domain and Application
- Integration tests for Infrastructure
- Functional tests for Web/API
-
MIGRATION_GUIDE.md - Step-by-step migration
- Phase 1: Extract interfaces ?
- Phase 2: Domain Layer ? (85% complete)
- Phase 3: Multi-project structure (optional)
- Phase 4: Comprehensive tests (in progress)
-
HYBRID-MAPPING-STRATEGY.md - AutoMapper + Custom Mapper ??
- Decision matrix for choosing mappers
- AutoMapper configuration and profiles
- Custom mapper for dynamic APIs
- Real-world usage examples
- Testing strategies and benchmarks
All dependencies point inward. Nothing in an inner layer knows about outer layers.
+-----------------------------------------+
� PRESENTATION LAYER �
� (Controllers, API, Blazor Components) �
� �
� ? Depends on �
+-----------------------------------------+
?
+-----------------------------------------+
� INFRASTRUCTURE LAYER �
� (Database, APIs, Services, Caching) �
� �
� ? Depends on �
+-----------------------------------------+
?
+-----------------------------------------+
� APPLICATION LAYER �
� (Use Cases, CQRS, MediatR) �
� �
� ? Depends on �
+-----------------------------------------+
?
+-----------------------------------------+
� DOMAIN LAYER �
� (Business Rules, Entities, Logic) �
� �
� ? Depends on NOTHING �
+-----------------------------------------+
Inner layers define what needs to be done (interfaces).
Outer layers provide how to do it (implementations).
// APPLICATION LAYER - Defines the contract
public interface IApiIntegrationService
{
Task<Result<T>> GetAllDataAsync<T>(string apiUrl);
}
// INFRASTRUCTURE LAYER - Provides implementation
public class ApiIntegrationService : IApiIntegrationService
{
// Implementation using IHttpClientFactory
}
// PRESENTATION LAYER - Uses via MediatR
[ApiController]
public class SampleController : ControllerBase
{
private readonly IMediator _mediator; // Only depends on abstractions
}Each component has a single, well-defined responsibility.
| Layer | Responsibility | Examples |
|---|---|---|
| Domain | Pure business rules (testable without framework) | User entity, Email value object, business validations |
| Application | Use cases and orchestration (CQRS) | LoginUserCommand, GetApiDataQuery, pipeline behaviors |
| Infrastructure | External concerns (frameworks, APIs, databases) | ApiIntegrationService, caching, EF Core |
| Presentation | User interaction (web/API) | Controllers, Blazor components, request models |
+-----------------------------------------------------------------+
� PRESENTATION LAYER �
� (CleanArchitecture.ApiTemplate.Web) �
� �
� � Blazor Server Components (UI) �
� � REST API Controllers (Endpoints) �
� � Middleware Pipeline �
� � Configuration & DI Setup �
� �
� Depends on: Application, Infrastructure, Infrastructure.Azure �
+-----------------------------------------------------------------+
� (Can reference all layers)
�
+--------------------+--------------------+
� � �
? ? ?
+---------------+ +-------------------+ +---------------------+
� INFRASTRUCTURE� � INFRASTRUCTURE � � (Azure-Specific) �
� (Generic) � � .AZURE � � �
� � EF Core � � � Key Vault � � �
� � API Client � � � Blob Storage � � �
� � Caching � � � Service Bus � � �
� � � � � �
� Depends on: � � Depends on: � � �
� Application � � Application � � �
+---------------+ +-------------------+ � �
� � �
+----------------------------------+ �
� �
� (Both implement interfaces from �
� Application layer) �
? �
+-----------------------+ �
� APPLICATION LAYER � �
� � �
� � Use Cases (CQRS) �?-----------------------+
� � Query Handlers �
� � Command Handlers �
� � Pipeline Behaviors �
� � Interfaces �
� �
� Depends on: Domain �
+-----------------------+
�
� (Uses domain entities
� and business rules)
?
+-----------------------+
� DOMAIN LAYER �
� �
� � User Entity � ? Complete
� � Token Entity � ? Complete
� � ApiDataItem Entity � ? Complete
� � Email Value Object � ? Complete
� � Role Value Object � ? New
� � Domain Enums � ? Complete
� �
� Depends on: NOTHING �
� (Pure C#, No deps) �
+-----------------------+
| Layer | Can Reference | Cannot Reference | Why? |
|---|---|---|---|
| Domain | Nothing | Application, Infrastructure, Presentation | Must remain pure - no framework dependencies |
| Application | Domain only | Infrastructure, Presentation | Defines abstractions; implementations inject at runtime |
| Infrastructure | Application, Domain | Presentation | Implements Application interfaces; never controls UI |
| Presentation | All layers | None (top layer) | Orchestrates all layers; entry point for requests |
? NEVER DO THIS:
// Domain referencing Application ?
namespace CleanArchitecture.ApiTemplate.Core.Domain.Entities;
using CleanArchitecture.ApiTemplate.Core.Application.Interfaces; // WRONG!
// Application referencing Infrastructure ?
namespace CleanArchitecture.ApiTemplate.Core.Application.Features;
using CleanArchitecture.ApiTemplate.Infrastructure.Services; // WRONG!✅ CORRECT APPROACH:
// Application defines interface ?
namespace CleanArchitecture.ApiTemplate.Core.Application.Common.Interfaces;
public interface IApiIntegrationService
{
Task<Result<T>> GetAllDataAsync<T>(string apiUrl);
}
// Infrastructure implements interface ?
namespace CleanArchitecture.ApiTemplate.Infrastructure.Services;
using CleanArchitecture.ApiTemplate.Core.Application.Common.Interfaces;
public class ApiIntegrationService : IApiIntegrationService
{
// Implementation...
}Status: ? 85% Complete
- Pure business logic and rules
- No external dependencies (only .NET BCL)
- Entities with behavior (not anemic)
- Value objects for type safety
- Domain exceptions
Current Implementation:
- ? User entity (authentication, roles, lifecycle)
- ? Token entity (JWT lifecycle, revocation)
- ? ApiDataItem entity (sync, cache management)
- ? Email value object (RFC 5321 validation)
- ? Role value object (permission hierarchy)
- ? 4 domain enums with comprehensive documentation
Status: ? Implemented
- Use cases (CQRS commands and queries)
- Business workflows
- Interface definitions
- DTOs and mapping ??
- ?? Hybrid Mapping Strategy Guide
- AutoMapper for known structures
- Custom mapper for dynamic APIs
- Pipeline behaviors
Key Components:
- MediatR for CQRS pattern
- CachingBehavior for automatic caching
- LoginUserCommand, BlacklistTokenCommand
- IsTokenBlacklistedQuery with caching
- ApiDataMappingProfile - AutoMapper configuration ??
Status: ? Implemented
- External service implementations
- Database access (EF Core configurations pending)
- Caching (Memory + Distributed)
- API integration
- File system access
Current Services:
- ApiIntegrationService
- TokenBlacklistService (dual-cache)
- JwtTokenGenerator
- CacheService
Status: ? Implemented
- HTTP controllers (API endpoints)
- Blazor components (UI)
- Middleware pipeline
- Request/response models
- Configuration
Features:
- Authentication endpoints (CQRS-based)
- Token blacklist admin endpoints
- Swagger/OpenAPI integration
- Custom middleware (JwtBlacklistValidationMiddleware)
CleanArchitecture.ApiTemplate/ (Single Project)
�
+-- Core/ # ?? CORE - Business Logic
� +-- Domain/ # ? 85% Complete
� � +-- Entities/
� � � +-- BaseEntity.cs ?
� � � +-- User.cs ? NEW
� � � +-- Token.cs ? NEW
� � � +-- ApiDataItem.cs ? NEW
� � +-- ValueObjects/
� � � +-- ValueObject.cs ?
� � � +-- Email.cs ?
� � � +-- Role.cs ? NEW
� � +-- Enums/
� � � +-- UserStatus.cs ?
� � � +-- TokenStatus.cs ?
� � � +-- TokenType.cs ?
� � � +-- DataStatus.cs ?
� � +-- Exceptions/
� � +-- DomainException.cs ?
� �
� +-- Application/ # ? CQRS Implementation
� +-- Common/
� � +-- Behaviors/ # Pipeline behaviors
� � +-- Interfaces/ # Service abstractions
� � +-- Models/ # Result<T>, DTOs
� +-- Features/
� +-- Authentication/ # Login, Logout commands
� +-- SampleData/ # API data queries
�
+-- Infrastructure/ # ?? External Concerns
� +-- Services/
� � +-- ApiIntegrationService.cs
� � +-- TokenBlacklistService.cs
� � +-- JwtTokenGenerator.cs
� +-- Caching/
� � +-- CacheService.cs
� +-- Handlers/
� � +-- ApiKeyHandler.cs
� +-- Middleware/
� +-- JwtBlacklistValidationMiddleware.cs
�
+-- Presentation/ # ?? UI & API
� +-- Controllers/v1/
� � +-- AuthController.cs # CQRS authentication
� � +-- TokenBlacklistController.cs
� +-- Extensions/
� +-- DependencyInjection/
� +-- HttpPipeline/
�
+-- Components/ # ??? Blazor UI
+-- Pages/
+-- Layout/
? Fast Development - Quick builds, no project reference management
? Simple Structure - Easy to navigate, less complexity
? Clear Organization - Folder-based layer separation
? Perfect for Solo/Small Teams - Maintains development velocity
For larger teams or enterprise applications, consider this structure:
CleanArchitecture.ApiTemplate.sln
+-- Core/
� +-- CleanArchitecture.ApiTemplate.Domain/ # Pure business logic
� +-- CleanArchitecture.ApiTemplate.Application/ # Use cases & interfaces
+-- Infrastructure/
� +-- CleanArchitecture.ApiTemplate.Infrastructure/ # Generic infrastructure
� +-- CleanArchitecture.ApiTemplate.Infrastructure.Azure/ # Azure-specific
+-- Presentation/
+-- CleanArchitecture.ApiTemplate.Web/ # Blazor + API
When to Consider Multi-Project:
- Team size > 5 developers
- Need strict boundary enforcement
- Sharing domain logic across multiple UIs
- Long-term enterprise application
CleanArchitecture.ApiTemplate implements a hybrid mapping strategy for transforming data between layers:
AutoMapper for Known Structures:
// Known API structure with strongly-typed DTO
var apiDto = await _apiService.GetAllDataAsync<ApiItemDto>(url);
var domainEntity = _autoMapper.Map<ApiDataItem>(apiDto);Custom Mapper for Dynamic APIs:
// Unknown/dynamic API structure
var dynamicResponse = await _apiService.GetAllDataAsync<dynamic>(url);
var domainEntities = _customMapper.MapToApiDataItems(dynamicResponse, url);When to Use Each:
- ? AutoMapper ? Internal APIs, known structures, Entity?DTO conversions
- ? Custom Mapper ? Third-party APIs, varying property names, dynamic structures
?? Full Guide: Hybrid Mapping Strategy Documentation
CleanArchitecture.ApiTemplate uses CQRS with MediatR for authentication:
Authentication Flow:
Controller ? MediatR ? Command/Query Handler ? Service ? Response
Login Command Example:
// 1. Command
public record LoginUserCommand(
string Username,
string Password,
string Role
) : IRequest<Result<LoginResponse>>;
// 2. Handler (Application Layer)
public class LoginUserCommandHandler
: IRequestHandler<LoginUserCommand, Result<LoginResponse>>
{
private readonly IJwtTokenGenerator _tokenGenerator;
public async Task<Result<LoginResponse>> Handle(...)
{
// Business logic: validate, generate JWT, return response
}
}
// 3. Controller (Presentation Layer)
[HttpPost("login")]
public async Task<IActionResult> Login([FromBody] LoginRequest request)
{
var command = new LoginUserCommand(request.Username, request.Password, request.Role);
var result = await _mediator.Send(command);
return result.Success ? Ok(result.Data) : BadRequest(result.Error);
}Benefits:
- ? Clean separation (Controller handles HTTP, Handler contains logic)
- ? Testable (handlers can be unit tested independently)
- ? Consistent error handling (Result pattern)
- ? Automatic caching (via ICacheable interface)
All entities use factory methods for creation:
// User entity
var email = Email.Create("user@example.com");
var user = User.Create("johndoe", email, hashedPassword);
user.AssignRole(Role.Admin);
// Token entity
var token = Token.Create(
userId: user.Id,
username: user.Username,
expiresAt: DateTime.UtcNow.AddMinutes(60),
type: TokenType.AccessToken
);
// ApiDataItem entity
var dataItem = ApiDataItem.CreateFromExternalSource(
externalId: "123",
name: "Sample Data",
description: "Description",
sourceUrl: "https://api.example.com/data/123"
);- ? Use factory methods for entity creation
- ? Validate in constructors/factory methods
- ? Use value objects to prevent primitive obsession
- ? Throw DomainException for business rule violations
- ? Keep entities rich with behavior (not anemic)
- ? Use MediatR for CQRS pattern
- ? Define interfaces for all infrastructure dependencies
- ? Use Result pattern for error handling
- ? Implement pipeline behaviors for cross-cutting concerns
- ? Implement Application layer interfaces
- ? Use HttpClientFactory for external APIs
- ? Use distributed caching for scalability
- ? Log all infrastructure operations
- ? Keep controllers thin (delegate to MediatR)
- ? Use DTOs for API requests/responses
- ? Implement proper error handling middleware
- ? Version your APIs
- Microsoft: .NET Architecture Guides
- Clean Code by Robert C. Martin
- Domain-Driven Design by Eric Evans
- 01-Domain-Layer.md - Domain implementation (85% complete)
- 02-Application-Layer.md - CQRS with MediatR
- 06-Testing-Strategy.md - Testing approach
- MIGRATION_GUIDE.md - Step-by-step migration
✅ Clear Architecture - Layers separated by responsibility
✅ Domain Layer - 85% complete with rich entities and value objects
✅ CQRS Pattern - Commands and queries separated via MediatR
✅ Testability - Business logic independent of frameworks
✅ Flexibility - Easy to swap implementations
✅ Scalability - Team can work on different features
✅ Maintainability - Clear code organization and flow
- 12 files with ~3,250 lines of domain code
- 3 entities: User (authentication/roles), Token (JWT lifecycle), ApiDataItem (API sync)
- 2 value objects: Email (RFC validation), Role (permission hierarchy)
- 4 enums: UserStatus, TokenStatus, TokenType, DataStatus
- 100% documented with XML comments and usage examples
- ? Review the domain entities and value objects
- ? Create EF Core configurations for entities
- ? Write unit tests for domain logic
- 🔗 Integrate with Application layer handlers
- ? Update repositories to use entities
- 🏛️ Clean Architecture is about organization and boundaries, not file count
- ? Single-project is fine for most teams (< 20 developers)
- ? Use abstractions to enforce dependency rules
- ? Keep Domain pure - no external dependencies
- ? CQRS + MediatR provides excellent structure
- ? Rich domain models are more maintainable than anemic ones
Questions about Clean Architecture?
- 📖 Documentation: See individual layer guides in
/docs/CleanArchitecture/Projects/ - 🐛 Issues: GitHub Issues
- 📧 Email: softevolutionsl@gmail.com
- 🐙 GitHub: @dariemcarlosdev
Getting Started:
- 💎 Start with domain - Review the created entities and value objects
- 🧪 Add tests - Write unit tests for domain logic
- 🔗 Integrate - Update handlers to use domain entities
- 📝 Document - Keep documentation up to date as you evolve
Clean Architecture is a journey, not a destination. Start with small improvements and build from there! ???
Last Updated: January 2025
Maintainer: Dariemcarlos
Repository: CleanArchitecture.ApiTemplate
Status: ? Current & Maintained
Branch: Dev
Domain Layer: 85% Complete