Skip to content

amitbytes/AmitBytes.CleanArchitecture

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 

Repository files navigation

AmitBytes.CleanArchitecture

.NET License

Clean Architecture reference implementation in .NET 10, designed to demonstrate separation of concerns, dependency inversion, and a practical Minimal API request flow.

Architecture Overview

The solution in src/AmitBytes.CleanArchitecture.slnx contains these projects:

  • Domain - core business model (Customers, value objects, domain exceptions).
  • Application - use cases/services and abstraction contracts (repository/service interfaces, DI installers).
  • Infrastructure - implementation details (repository implementations, entity configuration bootstrap).
  • Contract - API-facing DTO contracts.
  • AmitBytes.CleanArchitecture.Common - shared primitives (Result, Error, enum helpers).
  • Api/MinWebApi - main composition root and working Minimal API host.
  • Api/WebApi - secondary API host scaffold.

Dependency Direction

Dependencies point inward toward core business logic (compile-time project references):

  • Api/MinWebApi -> Application, Infrastructure
  • Api/WebApi -> Application, Contract
  • Infrastructure -> Application, Domain
  • Application -> Domain, Contract, AmitBytes.CleanArchitecture.Common
  • Domain has no project references
flowchart TB
subgraph apiLayer [API Layer]
minApi[Api MinWebApi]
webApi[Api WebApi]
end

subgraph infraLayer [Infrastructure Layer]
infrastructure[Infrastructure]
end

subgraph appLayer [Application Layer]
applicationContracts[Application ContractsAndServices]
contract[Contract DTOs]
common[Common ResultAndError]
end

subgraph domainLayer [Domain Layer]
domain[Domain EntitiesAndValueObjects]
end

minApi -->|"references"| applicationContracts
minApi -->|"references"| infrastructure
webApi -->|"references"| applicationContracts
webApi -->|"references"| contract
infrastructure -->|"references (uses app interfaces/contracts)"| applicationContracts
infrastructure -->|"references"| domain
applicationContracts -->|"references"| domain
applicationContracts -->|"references"| contract
applicationContracts -->|"references"| common
Loading

High-Level Request Flow

The primary runnable flow is in Api/MinWebApi, wired from Program.cs through endpoint and service installers.

flowchart LR
client[DeveloperClient] -->|"GET /api/customers/{id}"| minApi[MinWebApi]
minApi --> endpointInstaller[CustomerEndpointsRouteInstaller]
endpointInstaller --> appService[ICustomerService CustomerService]
appService --> repoContract[ICustomerRepository]
repoContract --> infraRepo[CustomerRepository]
infraRepo --> resultDomain[Result Customer]
resultDomain --> appService
appService --> responseDto[CustomerRead Contract]
responseDto --> client
Loading

Composition Root and Extensibility

src/Api/MinWebApi/Program.cs is the composition root:

  • AddApplicationServices(...) scans and registers IServiceInstaller implementations from Application.
  • AddInfrastructureServices(...) scans and registers IServiceInstaller implementations from Infrastructure.
  • UseInfrastructureEntityConfiguration() initializes and validates entity mappings at startup.
  • UseEndpointRoutesInstaller<Program>() discovers IEndpointsRouteInstaller implementations and maps routes.

This allows new features to be added with minimal changes to Program.cs: place new installers/endpoints in the expected folders and they are picked up automatically by reflection.

Project Structure

src/
├── AmitBytes.CleanArchitecture.Common/
├── Domain/
│   ├── Customers/
│   ├── ValueObjects/
│   └── Exceptions/
├── Application/
│   ├── Interfaces/
│   ├── Services/
│   ├── ServiceInstallers/
│   └── Extensions/
├── Infrastructure/
│   ├── Customers/
│   ├── Common/
│   ├── ServiceInstaller/
│   └── Extensions/
├── Contract/
│   └── Customers/
└── Api/
    ├── MinWebApi/
    └── WebApi/

Quick Start

Prerequisites

  • .NET 10 SDK
  • Git

Run Locally

dotnet restore src/AmitBytes.CleanArchitecture.slnx
dotnet build src/AmitBytes.CleanArchitecture.slnx
dotnet run --project src/Api/MinWebApi/AmitBytes.CleanArchitecture.MinWebApi.csproj

Local URLs

MinWebApi launch profiles:

  • https://localhost:7110
  • http://localhost:5266

WebApi launch profiles:

  • https://localhost:7102
  • http://localhost:5267

Smoke Test

After starting MinWebApi, call:

  • GET https://localhost:7110/api/weatherforecast
  • GET https://localhost:7110/api/customers/1 (requires a Customer row with that id in your database)

You can also use src/Api/MinWebApi/AmitBytes.CleanArchitecture.MinWebApi.http.

Onboarding Quick Path (30-60 Minutes)

  1. Run MinWebApi and verify weatherforecast endpoint works.
  2. Open src/Api/MinWebApi/Program.cs to understand startup wiring.
  3. Follow endpoint discovery via UseEndpointRoutesInstaller to RouteEndpoints.
  4. Trace CustomerEndpointsRouteInstaller -> ICustomerService -> CustomerRepository.
  5. Review Result and Error in AmitBytes.CleanArchitecture.Common for success/failure flow.

Implementation Guidelines

Add a New Business Feature

  1. Domain: add entity/value objects/exceptions under src/Domain.
  2. Application:
    • define repository interface under src/Application/Interfaces/Persistence/Repository.
    • define service interface/implementation under src/Application/Services.
    • register service in an IServiceInstaller under src/Application/ServiceInstallers.
  3. Infrastructure:
    • implement repository under src/Infrastructure/<Feature>/Persistence.
    • register implementation in an IServiceInstaller under src/Infrastructure/ServiceInstaller.
    • add entity configuration under src/Infrastructure/<Feature>/Configuration if needed.
  4. API (MinWebApi):
    • add an endpoint installer implementing IEndpointsRouteInstaller under src/Api/MinWebApi/RouteEndpoints.
    • use GlobalRoutePrefix from configuration when building route groups.
  5. Contract:
    • add/extend DTO records under src/Contract and map in application services.

Coding Conventions Used in This Repository

  • Prefer returning Result/Result<T> from service and repository boundaries.
  • Keep Domain free from infrastructure concerns.
  • Keep dependency direction inward (outer layers can depend on inner layers, not vice versa).
  • Use installers for DI rather than hard-coding registrations in Program.cs.
  • Keep route mapping in endpoint installer classes, not directly in startup.

Best Practices Followed in This Project

These are the implementation standards already followed in this repository and should be maintained for all upcoming changes:

  • Clean dependency direction: preserve inward project references (API -> Application -> Domain, with Infrastructure implementing Application contracts).
  • Separation of concerns by layer: keep business rules in Domain, orchestration in Application, and technical implementations in Infrastructure.
  • Contract-first boundaries: expose API/application payloads through Contract DTOs instead of leaking domain models directly.
  • Consistent success/failure handling: use Result and Error patterns to avoid exception-driven control flow across service boundaries.
  • Composition root discipline: keep startup wiring in Program.cs minimal and push registrations to installer classes.
  • Convention-based extensibility: implement IServiceInstaller and IEndpointsRouteInstaller so new services and routes are auto-discovered.
  • Endpoint thinness: keep endpoint handlers lightweight; delegate use-case logic to application services.
  • Async-first I/O boundaries: repository and service operations are asynchronous to support scalable API handling.

Developer Standard Checklist

Before raising a PR, ensure:

  • New feature code is placed in the correct layer and does not violate dependency direction.
  • New services/repositories are registered via installer interfaces, not ad-hoc startup code.
  • Endpoint logic remains orchestration-only (no embedded persistence/business complexity).
  • Returned responses use contract types and follow the Result-based error handling style.
  • Build and smoke tests pass locally for changed endpoints.

Testing and Validation Status

  • There are currently no test projects in this repository.
  • Use build + API smoke tests as the current validation path:
dotnet build src/AmitBytes.CleanArchitecture.slnx
dotnet run --project src/Api/MinWebApi/AmitBytes.CleanArchitecture.MinWebApi.csproj

As the next step, add dedicated test projects (Domain/Application/Infrastructure/API) and wire dotnet test into CI.

Current Limitations and Next Milestones

Current limitations

  • Local SQL Server must contain a Customer table matching entity configuration; otherwise customer reads will fail at runtime. Schema changes will be introduced later via a migration-based workflow (not ad-hoc SQL scripts in this repository).
  • Several generic repository methods are placeholders.
  • API key authentication handler exists but registration is commented out in Program.cs.

Suggested next milestones

  • Introduce a migration workflow for schema changes and environments.
  • Add automated tests per layer and enforce them in CI.
  • Expand endpoint coverage and error-path handling with consistent Result usage.

Contributing

  1. Fork the repository.
  2. Create a branch: git checkout -b feature/your-change.
  3. Implement and verify changes locally.
  4. Open a pull request with context and test notes.

License

This project is licensed under the MIT License. See LICENSE.

About

Clean Architecture Solution

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages