Rezaul Islam
All articles
Architecture

Clean Architecture in .NET: What Earns Its Keep

Four projects, a pile of interfaces, and a mapping layer nobody enjoys. Here is the part of clean architecture I keep, and the part I drop.

Rezaul Islam2 min read
Share

Almost every .NET codebase I have inherited in the last five years has the same four folders: Domain, Application, Infrastructure, Web. Sometimes that structure is carrying real weight. More often it is ceremony — an interface per class, a DTO per entity, and a mapper nobody wants to touch.

What I keep

The dependency rule. Domain knows nothing about the outside world; infrastructure depends inward, never the reverse. That single constraint is what lets you swap a database, add a second delivery mechanism, or test business rules without spinning up a server.

// Application layer: the contract lives with the use case
public interface IProjectRepository
{
    Task<Project?> GetBySlugAsync(string slug, CancellationToken ct);
}

// Infrastructure layer: EF Core knows about Application, not the reverse
public sealed class ProjectRepository(AppDbContext db) : IProjectRepository
{
    public Task<Project?> GetBySlugAsync(string slug, CancellationToken ct) =>
        db.Projects.AsNoTracking().FirstOrDefaultAsync(p => p.Slug == slug, ct);
}

What I drop

  • An interface for every service, whether or not a second implementation will ever exist
  • DTOs that are field-for-field copies of the entity, mapped by hand in both directions
  • A generic repository over an ORM that is already a repository
  • Layer-crossing abstractions added because a diagram said so, not because a change was painful

The honest test is this: point at an abstraction and name the change it is protecting you from. If nobody in the room can name one, it is not architecture — it is indirection with good PR.

  • #.NET Core
  • #Clean Architecture
  • #Patterns
Share

Ratings & reviews

Rate the article and leave a note — useful pushback is as welcome as agreement.

Reader rating

4.5out of 5

Based on 2 reviews

  • 51
  • 41
  • 30
  • 20
  • 10

Rate this article

Write a review

Was this useful, or did it miss something? Both are worth saying.

Your rating

2 reviews

  • Marta NowakSenior .NET Developer
    29 May 2026

    "Indirection with good PR" — I laughed and then deleted three interfaces.

  • Ahmed Siddiqui
    4 Jun 2026

    Fair take, though generic repositories still help me when teams are junior and consistency matters more than elegance.

Keep reading

Architecture

CQRS Without the Cargo Cult

Separating reads from writes solves a real problem. Most teams adopt the folder structure and none of the benefit.

2 min read

Let's Build Something Great.

I'm always open to discussing new opportunities, collaborations and interesting projects.

Rezaul Islam

Engineering ManagerSoftware Architect