Best ASP.NET MVC project structure for a minimal viable product?
I'm creating a minimal viable product in ASP.NET MVC. I read this section on the Microsoft website (https://learn.microsoft.com/en-us/dotnet/architecture/modern-web-apps-azure/common-web-application-architectures?utm_source) and I'm considering using a similar structure. However, would this be recommended? Is there another structure that is more generally used? I don't want it to be too advanced but it needs to have good separation of concerns.
Common web application architectures - .NET
Architect Modern Web Applications with ASP.NET Core and Azure | Explore the common web application architectures
4 Replies
This is the classic onion/clean architecture, used at probably most enterprise shops
A more modern approach would be vertical slice architecture
$vsa
Regarding clean architecture, we have a tag as well: $whynotca
Clean Architecture is not necessarily difficult to understand conceptually, but they're difficult to build and difficult to maintain. When you build a real project, you will quickly (as often evidenced on this server) run into questions like "Is this an infrastructure object or a domain object?" or "Should I implement this contract in the infrastructure or the application?". Questions that a) take your time to ponder and ultimately answer, and b) distract you from doing your actual work.
It also adds unnecessary abstractions, by forcing you to use layers: both unnecessary layers and unnecessary decoupling between layers. For example, CA would generally argue that you should abstract the database into repositories and services should depend on an interface for the repository. However, modern ORMs like EFC already implement the repository pattern, by abstracting the implementation of a query via LINQ. Furthermore, in most applications, there's only one implementation of
IXxxRepository - so why create the interface abstraction?
Instead, it's generally better to get rid of nearly all interfaces, keeping only ones that truly have more than one implementation; simplifying maintenance because any change to an api only needs to be done in one class instead of both class and interface. Smush all of the code down into a single Web project, or possibly two: Web and Services projects; removing any questions about "which project does this class go into?". Organize your code well in the Web project, with all of the User-related services/controllers/models/etc under /Features/Users/Xxx; all of the Order-related services/controllers/models/etc under /Features/Orders/Xxx; etc. Then it will be easy to find and maintain all of the code related to such and such feature. Any Infrastructure code (like emails, behaviors, startup code, etc.) can go under /Infrastructure/Xxx, and any non-infrastructure code that's not related to a feature can go under /Features/Shared.