DEV Community

Cover image for How to Structure a .NET Solution That Actually Scales: Clean Architecture Guide

How to Structure a .NET Solution That Actually Scales: Clean Architecture Guide

Mashrul Haque on December 01, 2025

A practical guide to Clean Architecture folder structure, project organization, and dependency management in .NET—battle-tested patterns that help ...
Collapse
 
mikebot profile image
MikeBot • Edited

MyApp.Application/
├── Features/
│ ├── Orders/
│ │ ├── Commands/
│ │ │ ├── PlaceOrder/
│ │ │ │ ├── PlaceOrderCommand.cs
│ │ │ │ ├── PlaceOrderHandler.cs
│ │ │ │ └── PlaceOrderValidator.cs
│ │ │ └── CancelOrder/
│ │ │ └── ...
│ │ └── Queries/
│ │ └── GetOrderById/
│ │ ├── GetOrderByIdQuery.cs
│ │ ├── GetOrderByIdHandler.cs
│ │ └── OrderDto.cs
│ └── Customers/
│ └── ...
├── Common/
│ ├── Behaviors/
│ │ ├── ValidationBehavior.cs
│ │ └── LoggingBehavior.cs
│ └── Interfaces/
│ └── IApplicationDbContext.cs
└── DependencyInjection.cs

The structure shown in your article isn’t actually vertical slicing. It’s essentially Clean Architecture with feature folders, as it still uses horizontal layers (Infrastructure, Application, Domain, Presentation) as the top architecture layering.

In true Vertical Slice Architecture, the feature itself is the top-level organizing unit, and each slice contains its own horizontal 'clean code' layers. The layers live inside the feature, not the other way around.
Each slice should be independent from each other, , so that it can be developed, tested, and deployed in isolation. This independence reduces coupling, makes the codebase easier to maintain, and allows features to evolve without affecting unrelated parts of the system.

Your example is still grouping by architectural concern, not by business capability. That’s horizontal layering, so it’s clean architecture, not vertical sliced architecture.

Collapse
 
mashrulhaque profile image
Mashrul Haque

You're technically correct that pure VSA would have each slice own everything top to bottom with no shared layers. What I'm showing is a hybrid: Clean Architecture's layer boundaries with VSA's feature-centric organization inside Application. I find this works better for most teams because an Order is an Order whether you're placing it or canceling it. Duplicating domain concepts across 15 independent slices creates more problems than it solves when you're building one product with shared business rules. The "meets CQRS lite" phrasing was meant to signal it's not pure VSA, but I get why that wasn't clear.

Collapse
 
voroninp profile image
Pavel Voronin

While we indeed put DTOs to Contracts project, I'd distinguish between the presentation layer (API) and the application layer.

Presentation DTO -> App Use Case parameters
Enter fullscreen mode Exit fullscreen mode

This gives us an opportunity to expose the same application using different presentation/transport. For example, protobuf DTOs differ from those serialised to JSON.
The price is an additional mapping layer, of course.

Collapse
 
alexanderbaggett profile image
Alexander Baggett • Edited

This outright assumes web dev is one and only type of .Net solution.

I'd ask you what the game dev equivalent is, but I suspect you lack the practical experience.

A lot of this would transfer to desktop app dev as well, but again, you've stated it as though .Net solutions were only used to build APIs

Collapse
 
mashrulhaque profile image
Mashrul Haque

Fair criticism. This is web/API focused because that's what I ship. The dependency rule and boundary principles apply to Unity, WPF, whatever, but the specific folder conventions are web-centric. I don't have production game dev experience so I wrote about what I actually know. If you've got a structure that works for game dev, please drop it in the comments.

Collapse
 
voroninp profile image
Pavel Voronin

Actually, there are going to be several shared projects. ;-) Kernel for domain, another one for infrastructure, and the one for very generic extension methods. In our company some of them are just internal NuGet packages.

Collapse
 
aini_putri profile image
Aini Putri

This was such a refreshingly honest and painfully relatable read 😄.
I love how you explained Clean Architecture like someone who's personally fought in the “47-projects-one-class” war. The folder examples hit a little too close to home!! especially the part where Misc is where dreams go to die. Been there, buried a few dreams myself.

Also, huge respect for the line “Break this rule once, and you've broken it forever.”
Honestly, that should be printed on a poster and taped above every junior dev’s monitor.

Fantastic breakdown, clear structure, and just the right amount of therapy for traumatized .NET developers. Great job! 🚀

Collapse
 
mashrulhaque profile image
Mashrul Haque

Ha, the 47-projects war left scars. Some of us are still in therapy. Glad the Misc folder line landed because I wrote that one from a very specific place of pain. And yeah, that dependency rule poster idea? I might actually make that. Would sell well at .NET conferences right next to the "It works on my machine" mugs. Thanks for reading!

Collapse
 
alexandru_maris_7887f7493 profile image
Alexandru Maris

I'm a fan of splitting up a simple project structure into the clean architecture folder and project structure primarily because it's keeps me employed. Sure, splitting your solution into 5+ projects and enforcing inward dependencies looks great on paper — until you spend half your sprint writing interface proxies and dependency tests that exist solely to satisfy an ivory-tower ‘dependency rule’ no one actually measured. For many teams this kind of Clean Architecture just trades hidden coupling for explicit boilerplate, slowing feature delivery with abstraction layers that add complexity instead of solving real problems.

Collapse
 
mashrulhaque profile image
Mashrul Haque

If you're spending half a sprint writing interface proxies and dependency tests, something's gone wrong. That's not Clean Architecture working as intended. That's ceremony cosplaying as structure. The goal is boundaries that prevent the kind of spaghetti that turns a "quick fix" into a three-day archaeology expedition. Five projects with clear ownership beats one project where everything touches everything and nobody can change anything without breaking something else. But yeah, if your app is a simple CRUD tool with two developers and no plans to grow? You don't need this. The article even says "start simple." Clean Architecture earns its keep when complexity arrives. Applying it to a weekend project is like wearing a helmet to check your mailbox.

Collapse
 
przem profile image
Przem

You suggest to have separate project per layer. Why? Assembly is deployment unit, not code organization unit. If you deploy everything together (as suggested by having single application project), then why not use single app project + single test project?

You mention NetArchTest - you can use it to guard dependencies between namespaces within a single project, there is no need to split the code into multiple assemblies.