Epoch 2 – Refactor to Clean Architecture

Business Story

The initial Product Service has been successfully created as a single ASP.NET Core Web API project.

As the project grows, placing all source code inside a single project will make it difficult to maintain, test, and scale.

The architecture team has decided to refactor the service into a Clean Architecture, separating responsibilities into multiple projects.


Learning Objectives

After completing this epoch, students will be able to:


Target Architecture

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
ProductService

                +----------------------+
                |   ProductService.API |
                +----------+-----------+
                           |
                           v
                +----------------------+
                | ProductService.Application |
                +----------+-----------+
                           |
                           v
                +----------------------+
                | ProductService.Domain |
                +----------------------+

                           ^
                           |
                +----------------------+
                | ProductService.Infrastructure |
                +----------------------+

Responsibilities

Project Responsibility
API HTTP endpoints, middleware, dependency injection
Application Use cases, DTOs, interfaces, validation
Domain Business entities, business rules
Infrastructure Database, repositories, external services

Step 1. Remove the Default Web API Project

Move to the src folder.

1
cd src

Rename the existing project.

1
mv ProductService ProductService.API

Rename the project file.

1
mv ProductService.API/ProductService.csproj ProductService.API/ProductService.API.csproj

Step 2. Remove the Old Project from the Solution

Return to the solution folder.

1
cd ..

Remove the old project.

1
dotnet sln remove src/ProductService.API/ProductService.API.csproj

Step 3. Create the Remaining Projects

Move into src.

1
cd src

Create the Application project.

1
dotnet new classlib -n ProductService.Application

Create the Domain project.

1
dotnet new classlib -n ProductService.Domain

Create the Infrastructure project.

1
dotnet new classlib -n ProductService.Infrastructure

Step 4. Add All Projects to the Solution

Return to the solution root.

1
cd ..
1
2
3
4
5
6
7
dotnet sln add src/ProductService.API/ProductService.API.csproj

dotnet sln add src/ProductService.Application/ProductService.Application.csproj

dotnet sln add src/ProductService.Domain/ProductService.Domain.csproj

dotnet sln add src/ProductService.Infrastructure/ProductService.Infrastructure.csproj

Verify:

1
dotnet sln list

Expected output:

1
2
3
4
src/ProductService.API/ProductService.API.csproj
src/ProductService.Application/ProductService.Application.csproj
src/ProductService.Domain/ProductService.Domain.csproj
src/ProductService.Infrastructure/ProductService.Infrastructure.csproj

Step 5. Configure Project References

API

1
dotnet add src/ProductService.API/ProductService.API.csproj reference src/ProductService.Application/ProductService.Application.csproj
1
dotnet add src/ProductService.API/ProductService.API.csproj reference src/ProductService.Infrastructure/ProductService.Infrastructure.csproj

Application

1
dotnet add src/ProductService.Application/ProductService.Application.csproj reference src/ProductService.Domain/ProductService.Domain.csproj

Infrastructure

1
dotnet add src/ProductService.Infrastructure/ProductService.Infrastructure.csproj reference src/ProductService.Application/ProductService.Application.csproj
1
dotnet add src/ProductService.Infrastructure/ProductService.Infrastructure.csproj reference src/ProductService.Domain/ProductService.Domain.csproj

Dependency Graph

1
2
3
4
5
6
7
               API
              /   \
             /     \
    Application   Infrastructure
           \          /
            \        /
              Domain

The Domain project does not reference any other project.


Step 6. Build the Solution

1
dotnet build

Expected output:

1
Build succeeded.

Step 7. Verify the Folder Structure

1
2
3
4
5
6
src

├── ProductService.API
├── ProductService.Application
├── ProductService.Domain
└── ProductService.Infrastructure

Why Use Clean Architecture?

Without Clean Architecture

1
2
3
4
5
6
7
8
9
10
Controllers
Database
Business Logic
Validation
Repositories
DTOs

↓

Everything inside one project

Problems:


With Clean Architecture

1
2
3
4
5
6
7
8
9
10
11
12
13
Presentation

↓

Application

↓

Domain

↑

Infrastructure

Benefits:


Hands-on Exercise

Complete the following tasks:


Definition of Done

By the end of this epoch, students should have: