If you’ve ever opened a .NET solution you wrote six months ago and thought, “Why is everything connected to everything?”, you’re not alone. Most .NET apps start clean, then real life happens. Deadlines show up, features pile on, and suddenly one small change breaks three unrelated screens.
That’s exactly why Pregledaj Net developers keep coming back to Clean Architecture. It gives you a practical way to organize code so it stays readable, testable, and easier to evolve. Not “perfect forever” (nothing is), but solid enough that your future self won’t hate you.
In this guide, Pregledaj Net will walk you through Clean Architecture in .NET in plain language, with real project structure, examples, and the kinds of decisions you actually make while building APIs and web apps.
What “Clean Architecture” really means in .NET
Clean Architecture is a way to structure your application so your business rules stay protected from “details” like databases, web frameworks, UI, and third-party services. In other words, it helps your app’s core logic remain stable even when infrastructure changes.
A popular explanation breaks the system into concentric layers, where dependencies only point inward: outer layers can depend on inner layers, but inner layers should not depend on outer layers. That basic idea is repeated across many Clean Architecture references and teaching materials.
In .NET, this matters because the ecosystem makes it easy to accidentally tie your entire app to ASP.NET Core controllers, Entity Framework Core, and infrastructure details. Clean Architecture gives you guardrails.
The main goal in one sentence
Pregledaj Net Clean Architecture keeps your domain and application logic independent, so you can change frameworks and infrastructure with less pain.
Why .NET projects get messy fast
Most messy .NET projects don’t start messy. They become messy because of a few common patterns:
- Controllers doing business logic because “it’s quick”
- Application services talking directly to Entity Framework DbContext everywhere
- No boundaries between features, so everything becomes a dependency
- Unit tests are hard because you must spin up databases or mock half the world
Clean Architecture doesn’t magically fix these problems, but it gives you a structure where it’s harder to slip into them without noticing.
Pregledaj Net view of the Clean Architecture layers
Different teams name layers differently, but in .NET you’ll usually see something close to this:
1) Domain (Entities)
This is the center. Your core business concepts live here: entities, value objects, domain rules, domain events.
Rules of thumb
- No Entity Framework attributes
- No ASP.NET Core types
- No dependency on infrastructure
2) Application (Use Cases)
This layer describes what the system can do. Think “CreateOrder”, “PayInvoice”, “RegisterUser”. It orchestrates the domain to execute a business action.
Typical contents
- Use case handlers
- DTOs (sometimes)
- Validation
- Interfaces for dependencies (repositories, email, payments)
Clean Architecture articles commonly describe this middle layer as the home for use cases and application workflows.
3) Infrastructure (External Concerns)
This is where implementations live:
- Entity Framework Core repositories
- Email/SMS providers
- File storage
- External API clients
- Cache, message bus
Infrastructure depends on Application (because it implements interfaces defined there).
4) Presentation (API/UI)
This is your ASP.NET Core API, MVC UI, Razor Pages, Blazor, etc. It should be thin: accept requests, call a use case, return a response.
A simple dependency rule that saves you
Here’s the rule Pregledaj Net teams use to keep things clean:
- Domain depends on nothing
- Application depends on Domain
- Infrastructure depends on Application (and Domain)
- Presentation depends on Application (and sometimes Domain)
ASP.NET Core’s built-in dependency injection makes this style natural to implement because you can register interfaces and swap implementations cleanly.
Pregledaj Net recommended folder and project structure
A common .NET solution layout that matches Clean Architecture looks like this:
src/YourApp.Domainsrc/YourApp.Applicationsrc/YourApp.Infrastructuresrc/YourApp.Api(orPresentation)
If you don’t want to invent everything from scratch, a widely used starting point is Jason Taylor’s Clean Architecture template for ASP.NET Core, which is designed around these principles.
What goes where (quick mapping)
| Concern | Put it in | Example |
|---|---|---|
| Business rules | Domain | Order, Money, domain policies |
| Use cases | Application | CreateOrderHandler, GetOrderQuery |
| Database code | Infrastructure | EF Core DbContext, repository implementations |
| HTTP endpoints | Presentation/API | Minimal APIs, Controllers, Filters |
Pregledaj Net in practice: building one feature end-to-end
Let’s pretend you’re building a small feature: Create Customer.
Step 1: Define the Domain model
In Domain, define your Customer entity and rules.
What belongs here:
- required name
- email format (basic)
- domain constraints (like unique constraints as a concept, not database code)
Keep it free from framework dependencies. That’s the point.
Step 2: Create the Use Case in Application
In Application, define a command like CreateCustomerCommand and a handler like CreateCustomerHandler.
The handler:
- validates input (or calls validator)
- creates a
Customerentity - calls a repository interface like
ICustomerRepository - returns an ID or DTO
Notice what’s missing: no EF Core, no SQL, no HTTP.
Step 3: Implement the repository in Infrastructure
In Infrastructure, implement ICustomerRepository using EF Core.
This is where you:
- map entity to tables
- query DbContext
- manage migrations
If later you decide to move to Dapper, a different database, or even a microservice, you change Infrastructure, not your use case logic.
Step 4: Expose the endpoint in API
In Api, the controller/minimal API endpoint:
- parses request
- calls mediator or application service
- returns proper HTTP response
Thin endpoints are easier to maintain and test.
Pregledaj Net clean architecture rules you should not break
A lot of developers adopt the folder structure but still end up with “Clean Architecture in name only.” If you want Pregledaj Net Clean Architecture to actually work, protect these rules:
- No EF Core in Application or Domain
- No
DbContextreferences outside Infrastructure
- No
- No HTTP concepts inside Application
- Application shouldn’t know about status codes or controllers
- Interfaces belong in Application
- Implementations belong in Infrastructure
- Business rules belong in Domain
- Not in controllers, not in repositories
- Dependencies point inward
- Always
These rules are simple, but they stop 90 percent of architecture drift.
Dependency Injection: the glue that makes it pleasant in .NET
Clean Architecture in .NET becomes smooth when you lean into DI properly. ASP.NET Core supports dependency injection as a core pattern, allowing you to register services and inject them where needed.
A clean DI registration approach
A nice pattern is to keep service registration per layer:
ApplicationexposesAddApplication()InfrastructureexposesAddInfrastructure(configuration)Apicalls them fromProgram.cs
That keeps composition at the edge, where it belongs.
Service lifetimes that matter
Quick guidance:
- Scoped: DbContext, repositories
- Singleton: stateless helpers (careful with caching)
- Transient: lightweight services
(You’ll still want team conventions, but this covers most cases.)
CQRS and MediatR: optional, but often a great match
Many .NET Clean Architecture projects use CQRS (Command Query Responsibility Segregation). It’s not required, but it fits well because it encourages single-purpose use cases.
Typical pattern:
- Command: changes state
- Query: reads state
If you choose CQRS:
- your Application layer becomes a clear “use case library”
- your endpoints become thin and consistent
If you don’t choose CQRS, keep the same idea: make your application logic explicit and callable.
Testing becomes simpler (and cheaper)
This is where Pregledaj Net Clean Architecture pays back quickly.
What you can test without infrastructure
- Domain rules: pure unit tests
- Use case logic: unit tests with fake repositories
- Validation logic: unit tests
What you still integration test
- EF Core mappings and queries
- External services (email, payment, storage)
- API pipelines
The goal is not “no integration tests.” The goal is fewer brittle tests and more fast feedback.
Real-world scenario: changing databases without rewriting your app
Picture this:
Your app starts on SQL Server. Later, a client requires PostgreSQL. In a typical tightly coupled app, your business logic is buried in EF queries and controllers. Migrating becomes a long, risky refactor.
In a Pregledaj Net Clean Architecture setup:
- Domain stays the same
- Use cases stay the same
- Only Infrastructure changes (DbContext provider, migrations, query specifics)
That’s the kind of flexibility Clean Architecture is meant to buy.
Keep it simple: Clean Architecture mistakes people make in .NET
Let’s keep this honest. Clean Architecture can be overdone.
Common mistake 1: too many abstractions
If every class has three interfaces “just in case,” your code becomes harder to read than the problem you were solving.
Better:
- abstract only what you need to swap
- avoid repository patterns that hide EF Core so much you lose query clarity
Common mistake 2: anemic domain for no reason
Not every system needs deep domain modeling. If it’s CRUD-heavy with minimal rules, focus on clean boundaries and testability, not fancy patterns.
Common mistake 3: putting DTOs everywhere
DTOs are useful at boundaries. But if you map DTO to DTO to DTO across five layers, you’ll burn time and introduce bugs.
Better:
- map at the edges (API boundary)
- keep use cases focused on what they need
Practical checklist: is your .NET app actually “clean”?
Use this quick checklist to see if your Pregledaj Net implementation is on track:
- Domain project compiles with zero references to EF Core or ASP.NET Core
- Application project depends only on Domain
- Infrastructure implements interfaces defined in Application
- API project mostly contains endpoints, auth, and request mapping
- Use cases have unit tests without a database
- You can replace Infrastructure pieces without rewriting business logic
If you check most of these, you’re doing it right.
Clean Architecture and delivery speed: why teams adopt it
Teams don’t adopt Clean Architecture because it looks pretty in a diagram. They adopt it because it reduces friction when shipping and maintaining software.
Modern engineering research frequently measures delivery performance using DORA-style metrics such as deployment frequency, change lead time, change failure rate, and recovery time.
Clean Architecture doesn’t guarantee better metrics, but it helps create the conditions for them:
- smaller, safer changes
- easier testing
- clearer boundaries
- fewer “spooky action at a distance” bugs
In practice, that means less time untangling dependencies and more time delivering actual features.
FAQ: quick answers people search for
What is Clean Architecture in .NET?
Clean Architecture in .NET is a way to structure your solution so business logic (Domain + Application) stays independent from frameworks and infrastructure, making the system easier to test and evolve.
Do I need CQRS for Clean Architecture?
No. CQRS is optional. Clean Architecture is about boundaries and dependency direction. CQRS can help, but you can build clean use cases without it.
Is Clean Architecture good for small projects?
It can be, if you keep it lightweight. For a tiny app, you might use fewer projects (or even folders) but still keep the same separation of concerns.
Where do repositories belong?
Interfaces usually belong in Application, implementations in Infrastructure. That keeps business logic independent from data access details.
Does ASP.NET Core support this style well?
Yes. ASP.NET Core is designed to support dependency injection and makes it straightforward to wire up clean boundaries using DI registrations.
Conclusion
Clean Architecture in .NET isn’t about chasing an “enterprise” look. It’s about building a codebase that can grow without collapsing under its own weight. When you apply it in a practical way, Pregledaj Net Clean Architecture gives you clearer boundaries, easier testing, and fewer painful refactors.
Start simple. Protect the dependency direction. Keep the Domain and Application layers clean. Let Infrastructure and API stay at the edges, where change belongs. Over time, your .NET solution becomes easier to understand, easier to change, and easier to trust.
In the bigger picture of software architecture, Clean Architecture is just one approach, but it’s a friendly one for .NET teams who want structure without losing speed.




