Skip to content

Latest commit

 

History

History
791 lines (637 loc) · 28.4 KB

File metadata and controls

791 lines (637 loc) · 28.4 KB

??🏛️ Clean Architecture Guide for CleanArchitecture.ApiTemplate

? 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


📑 Table of Contents

Quick Navigation

  1. Overview
  2. Why Clean Architecture?
  3. Current Project Status
  4. Architecture Principles
  5. Documentation Structure
  6. Dependency Flow
  7. Layer Responsibilities
  8. Single-Project Implementation
  9. Multi-Project Solution Layout
  10. Implementation Guidance
  11. Best Practices
  12. Resources

📖 Overview

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

💡 Why Clean Architecture?

Problems We're Solving

? 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

Solutions Clean Architecture Provides

? 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)

For CleanArchitecture.ApiTemplate Specifically

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.


?? Current Project Status

Current State: Single-Project with Domain Layer

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

?💎 Domain Layer Progress Tracker

✅ Completed Components (85%)

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

? Remaining Work (15%)

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

Challenges & Solutions

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)

📚 Documentation Structure

All Clean Architecture documentation is in docs/CleanArchitecture/ directory.

Layer-Specific Guides

  1. 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)
  2. 02-Application-Layer.md

    • CQRS with MediatR
    • Query and Command handlers
    • Pipeline behaviors (Caching, Validation, Logging)
    • Interface abstractions
    • Examples: GetApiDataQuery, LoginUserCommand
  3. 03-Infrastructure-Layer.md

    • EF Core database context and migrations
    • API integration services
    • Caching implementations
    • Email and background services
  4. 04-Infrastructure-Azure-Layer.md

    • Azure Key Vault integration
    • Blob Storage service
    • Service Bus messaging
    • Application Insights
  5. 05-Web-Presentation-Layer.md

    • Blazor Server components
    • REST API controllers with versioning
    • Custom middleware
    • Configuration and DI setup
  6. 06-Testing-Strategy.md

    • Unit tests for Domain and Application
    • Integration tests for Infrastructure
    • Functional tests for Web/API

Implementation Guides

  • 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

??? Architecture Principles

Principle 1: Dependency Rule

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                 �
+-----------------------------------------+

Principle 2: Abstractions Over Implementations

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
}

Principle 3: Separation of Concerns

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

🔄 Dependency Flow (Clean Architecture Rules)

?? Visual Dependency Flow

+-----------------------------------------------------------------+
�                     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)   �
               +-----------------------+

?? Dependency Rules Table

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

?? Dependency Violations (Anti-Patterns)

? 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...
}

📋 Layer Responsibilities

Domain Layer (Core/Domain/)

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

Application Layer (Core/Application/)

Status: ? Implemented

  • Use cases (CQRS commands and queries)
  • Business workflows
  • Interface definitions
  • DTOs and mapping ??
  • Pipeline behaviors

Key Components:

  • MediatR for CQRS pattern
  • CachingBehavior for automatic caching
  • LoginUserCommand, BlacklistTokenCommand
  • IsTokenBlacklistedQuery with caching
  • ApiDataMappingProfile - AutoMapper configuration ??

Infrastructure Layer (Infrastructure/)

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

Presentation Layer (Presentation/ + Components/)

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)

📦 Single-Project Clean Architecture

Current Structure

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/

Benefits of Single-Project Approach

? 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


🏢 Multi-Project Solution Layout

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

🎯 Implementation Guidance

Data Transformation Patterns ??

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


Authentication with CQRS ? Featured Pattern

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)

Domain Entity Creation Pattern

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"
);

✅ Best Practices

Domain Layer

  • ? 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)

Application Layer

  • ? Use MediatR for CQRS pattern
  • ? Define interfaces for all infrastructure dependencies
  • ? Use Result pattern for error handling
  • ? Implement pipeline behaviors for cross-cutting concerns

Infrastructure Layer

  • ? Implement Application layer interfaces
  • ? Use HttpClientFactory for external APIs
  • ? Use distributed caching for scalability
  • ? Log all infrastructure operations

Presentation Layer

  • ? Keep controllers thin (delegate to MediatR)
  • ? Use DTOs for API requests/responses
  • ? Implement proper error handling middleware
  • ? Version your APIs

📚 Resources

Official Documentation

Architecture Patterns

Project-Specific Guides


📝 Summary

What CleanArchitecture.ApiTemplate Achieves

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

Domain Layer Highlights

  • 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

Next Steps

  1. ? Review the domain entities and value objects
  2. ? Create EF Core configurations for entities
  3. ? Write unit tests for domain logic
  4. 🔗 Integrate with Application layer handlers
  5. ? Update repositories to use entities

Key Takeaways

  • 🏛️ 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

🆘 Support

Questions about Clean Architecture?

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