-
Notifications
You must be signed in to change notification settings - Fork 1
Structuring folders in a project
The standard way of structuring an ASP.NET MVC/Web API project goes something like this:
- Project
- Controllers
- UserController.cs
- GameController.cs
- Models
- UserModel.cs
- GameModel.cs
- Views
- UserView.cs
- GameView.cs
Blazor seems to be following a similar pattern. This pattern is fine except it isn't. It actually is kind of messy.
Imagine what this looks like when you have a complex project. Let's add a bunch more "things" we need Models, Views, and Controllers for.
- Project
- Controllers
- UserController.cs
- GameController.cs
- CreatureController.cs
- RaceController.cs
- RoleController.cs
- AttributeController.cs
- SkillGroupController.cs
- AdventureController.cs
- ItemController.cs
- InventoryController.cs
- ExperienceController.cs
- RollController.cs
- Models
- UserModel.cs
- GameModel.cs
- CreatureModel.cs
- RaceModel.cs
- RoleModel.cs
- AttributeModel.cs
- SkillGroupModel.cs
- AdventureModel.cs
- ItemModel.cs
- InventoryModel.cs
- ExperienceModel.cs
- RollModel.cs
- Views
- UserView.cs
- GameView.cs
- CreatureView.cs
- RaceView.cs
- RoleView.cs
- AttributeView.cs
- SkillGroupView.cs
- AdventureView.cs
- ItemView.cs
- InventoryView.cs
- ExperienceView.cs
- RollView.cs
At this point, you've got every developer needing to sift through every folder to see what they need to work on. Even if it's only you working on this project, you're constantly mentally filtering out all the stuff you don't need to work on right now because it's all blended together. For most things you need to work on, this means you almost may as well not have any folders at all! Ok, you can use Areas, but even those tend to get messy over time and even then, you still see the Controllers/Models/Views folders, so you may get to a point of having 1 file per folder. Also messy!
At the same time, let's suppose we're thinking that we may go to microservices at some point, but don't want to commit to that until we're sure we've got a big enough project and team to go that route. With the above mishmash, you end up having to go one by one because this is, again, about the same as having no organization at all.
In Blazor, we see a similar structure in the sample project.
- Pages
- Counter.razor
- FetchData.razor
- ...
- Data
- WeatherForecast.cs
- WeatherForecastService.cs
The logical inference is you shouldd keep putting razor in Pages and data/services in Data.
Even outside of ASP.NET we often see structures like the one below all jumbled together.
- MyProject.csproj
- Entities
- Managers
- Repositories
Regardless of kind off project, this kind of folder structure continues to propagate the notion that type of object should govern what folder it is in.
What's an alternative? Organize by collaboration, not type. You will see this is starting to be built out in the Blazor client.
- BlazorFormSample.Client
- GameSystem
- GameSystemEditor.razor
- GameSystemList.razor
- GameSystemService.cs
- SharedComponent
- EditModel.cs
- EditToolbar.razor
- IEditModel.cs
- IService.cs
- ServiceBase.cs
- ...
I'm still refining as we grow (and will always), but the main point is that if I ever decide to pull out component libraries, I can start to see what is likely to depend on other things just by glancing at the folder structure. If I'm working on the GameSystem components, I don't need to deal with sifting through files, they're all right there.
This feels a lot more organized to me. Nothing is ever perfect, but I'm spending less time sifting and usually only need to have a couple of folders open, not every folder in the whole solution. Also, while it can't be absolutely sure that you're not overly-coupling components or such, it does help remind you when you're about to couple to another namespace (files in another folder). Avoiding that coupling can really reduce effort required when you organize into microservices or do some other form of reorganization at the component level at some point. This is also how many JavaScript frameworks recommend organizing, so I'm not doing anything new, just sharing what I think works better for many projects.
-- Jim Leonardo, 2020 09 24