Clean Architecture, introduced by Robert C. Martin (Uncle Bob), aims to create systems that are:
- Independent of frameworks
- Testable
- Independent of UI
- Independent of database
- Independent of any external agency
Clean Architecture emphasizes separating the concerns of different parts of the system and ensuring that each part has a clear responsibility.
.NET clean architecture as a development approach, available in a layered form to reduce dependency.
The architecture consists of several layers, each with a specific role and dependencies that flow in one direction: from the outer layers to the inner layers.
Inner most Layer is independent to its outer layer, means inner most layer does not have any references, it builds and stand independently.
Dependency Rule
The core principle of Clean Architecture is the Dependency Rule, which states that source code dependencies can only point inward. This means:
- Nothing in inner circle can depend on anything in an outer circle.
- Data formats and structures should also follow this rule.
Infrastructure Layer and Presentation Layer are outer most layer so these two layers does not depend on each other.
The main four layers of clean architecture consist of below layers:
- Domain Layer
- Application Layer
- Infrastructure Layer
- Presentation Layer
I have created project for better understanding, let’s Learn in detail.

I have created below Diagram for better understanding.

Key Points
a. Database implementation happens on Infrastructure layer so consider we connected to SQL database and tomorrow if requirement changes then and client says we need to change database to oracle then we can do with impacting other part of application
b. Similarly, Presentation Layer, today in this example we have used api end point and instead of it we want to use ASP.net MVC or any other UI framework we can use it without impacting rest of application.
Domain Layer
This layer Consist of business Models and entities
Example
This layer will have entities like below
namespace Domain.Entities
{
public class Customer
{
public int Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
}
}
Project screen shot

Application Layer
The application layer resides in the middle of the presentation and domain layer and functions as an intermediate between them. Primarily, it maintains the data between corresponding layers but is independent of the infrastructure and presentation layer.
This layer contains Interfaces and classes for all Use cases or Business Logic like below
Application Layer Dependent on domain layer, means this layer need to add reference of Domain layers or entities

Use Cases -> Defining Interfaces for CRUD operations
using Domain.Entities;
using System.Threading.Tasks;
namespace ApplicationLayer.Interfaces
{
public interface ICustomerRepository
{
void Add(Customer customer);
Customer GetById(int id);
IEnumerable<Customer> GetAll();
}
}
Implementation of Use Cases
using Domain.Entities;
using ApplicationLayer.Interfaces;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ApplicationLayer.UseCases
{
public class CreateCustomer
{
private readonly ICustomerRepository _repository;
public CreateCustomer(ICustomerRepository repository)
{
_repository = repository;
}
public void Execute(Customer customer)
{
// Business logic for creating a customer
_repository.Add(customer);
}
}
}
Infrastructure Layer
This layer Contains of DbContext class for database connection and repository classes which will implement ICustomerRepository interface defined on Applicaiton layer.
This layer Depend on Application layer and Domain layer

DB Context classes
using Microsoft.EntityFrameworkCore;
using Domain.Entities;
namespace Infrastructure.Data
{
public class AppDbContext : DbContext
{
public AppDbContext(DbContextOptions<AppDbContext> options) : base(options)
{
}
public DbSet<Customer> Customers { get; set; }
}
}
Customer Repository class
using Domain.Entities;
using Infrastructure.Data;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ApplicationLayer.Interfaces;
namespace Infrastructure.Repository
{
public class CustomerRepository : ICustomerRepository
{
private readonly AppDbContext _context;
public CustomerRepository(AppDbContext context)
{
_context = context;
}
public void Add(Customer customer)
{
_context.Customers.Add(customer);
_context.SaveChanges();
}
public Customer GetById(int id)
{
return _context.Customers.Find(id);
}
public IEnumerable<Customer> GetAll()
{
return _context.Customers.ToList();
}
}
}

We can see here Add Use case have reference of application Layer.
Dependency Injection
using Core.Interfaces;
using Infrastructure.Data;
using Microsoft.Extensions.DependencyInjection;
namespace Infrastructure.DI
{
public static class DependencyInjection
{
public static IServiceCollection AddInfrastructure(this IServiceCollection services)
{
services.AddDbContext<AppDbContext>(options =>
options.UseSqlServer("YourConnectionString"));
services.AddScoped<ICustomerRepository, CustomerRepository>();
return services;
}
}
}
Presentation Layer
This layer we use to execute our action; this you can call as UI layer but, in our cases, this is Controller class from where user start action.
This layer depends on Domain Layer and Applicaiton Layer only

using Core.Entities;
using Core.UseCases;
using Microsoft.AspNetCore.Mvc;
namespace WebApi.Controllers
{
[ApiController]
[Route("api/[controller]")]
public class CustomerController : ControllerBase
{
private readonly CreateCustomer _createCustomer;
public CustomerController(CreateCustomer createCustomer)
{
_createCustomer = createCustomer;
}
[HttpPost]
public IActionResult Create(Customer customer)
{
_createCustomer.Execute(customer);
return Ok();
}
}
}
Code flow
[User] -> [Web (Controllers)] -> [Core (UseCases)] -> [Core (Interfaces)] -> [Infrastructure (Data)] -> [Database]
- User sends a request to add a Customer.
- Web Layer (CustomerController) receives the request and converts the input to a domain entity.
- Core Layer (Use Case) processes the business logic.
- Core Layer (Interface) defines the contract for data operations.
- Infrastructure Layer (Data) implements the contract and performs database operations.
Conclusion
We have understood each layer in detail.
Please clap if this is adding any value to your knowledge.
Comments
Post a Comment