Interface Oriented Code Organization(IOCO)
I realized that the simplest place for the test would be in a folder structure that matched the UI for a web app or the API for a web API, and then quickly realized it would be helpful to have the production code folder structure match as well.
I had been working on several large complex code bases, some web apps, and some web APIs, and trying to find the code that needed to change or where to add new code wasn't obvious from the code organization.
The code was organized in the layered architecture style with UI layer, Service Layer, Repository Layer, etc. kind of like the structure Microsoft uses in "Traditional N-Layer architecture applications".
With folders for Controllers, Views, ViewModels, etc.
This architecture-oriented code organization(AOCO) is really good at telling you what architecture the solution is using but not so great at pointing you to where functionality X is residing.
And even worse there is no single place where functionality X is residing.
Some of it's in the Controllers folder, the Services folder, the ViewModels folder, the Views folder, etc.
Could you spread out the functionality any further?
I find that it would perhaps be better for the code organization to point you in the direction of where most of the code for functionality X is residing based on the UI/API.
This has several benefits beyond just making it simpler to navigate the code.
It makes the code more modular.
It makes the code more cohesive, the code that changes together stays together.
I did some googling to see if this is something that others have started doing as well.
I found a few:
Vertical Slice Architecture by Jimmy Bogard
Organizing Code by Feature using Vertical Slices by Derek Comartin
And I found this tweet by Jessica Joy Kerr, which sums it up nicely:
Group files by function (what value do they enable?) not type (view, model, etc).— Jessica Joy Kerr (@jessitron) August 23, 2019
Your code wants cross-functional teams too 😃
These are all similar to what I envisioned, I just like to also have the code organization match the UI/API as closely as possible.
If there is common code across folders, then it's a judgment call to pull that code out to its own folder that doesn't match the UI/API and sacrifice modularity to remove duplication.
I refactored most of the Web project code into the following top-level folders of the Web project:
These folders were chosen based on the URL, for example, Manage comes from https://localhost:44315/manage/my-account.
Although I had to make an exception for Catalog which is the default page and has just the site URL https://localhost:44315/ so in this case, I used the page title as the folder.
In the process I removed the Extensions, Interfaces, Pages, Services, ViewModels\Manage, Views\Manage, and Views\Order folders:
All that is left in the Controllers folder is the BaseApiController.cs
I left the Areas folder because it is hardcoded in the .NET source code and can't be customized.
I left the ViewModels\Account folder and the following in the Views folder as they are needed for login security and I didn't want to mess with it.