First off, let’s agree that namespace should match folder structure and that each language artefact should be in its own file.
(see Should the folders in a solution ma
I think you need to define a cut-off point where the flat approach no longer works. For example, if you have a typical 3-tier architecture in a smallish project, having 3 projects on the outer level is no problem. However, if you have a few dozen, then some sort of grouping helps segment functionality and makes the whole solution more understandable.
12 Years on, is there any definitive or best practice answer on this question?
I would like to use the Nested folders structure, however given that you:
"agree that namespace should match folder structure and that each language artefact should be in its own file."
How would project A.B.C.csproj folder structure look if it extended code from other namespaces, for example:
Perhaps something like:
/A // namespace: A
/B // namespace: A.B
/C // namespace: A.B.C
A.B.C.csproj
ClassC.cs
/_ // External Namespace root folder (underscore with no text)
/System // namespace: System
/Linq // namespace: System.Linq
IQueryableExtensions.cs
/Microsoft // namespace: Microsoft
/Extensions // namespace: Microsoft.Extensions
/Logging // namespace: Microsoft.Extensions.Logging
ILoggerExtensions.cs
/__A // namespace: A (Grand Parent folder (2 underscores for 2 levels up)
ClassAExtensions.cs
/B // namespace: A.B (Nested Parent folder)
ClassBExtensionsNested.cs
//Parent Namespace folder (1 underscore for 1 level up)
/_B // namespace: A.B
ClassBExtensions.cs
/D // namespace: A.B.C.D (Child folder)
ClassDExtensions.cs
Above is trying to demonstrate:
I'm not a big fan of nested projects, since it buries projects deep inside a structure and if you need to reuse that project in another application then what do you do, copy/paste the code? I like to follow somewhat of a flat structure but organized by namespace.
This is how I do it:
- DataHelpers\
---Factory\
---DataAccess\
---...
- Components\
--- EmailProcessor\
--- ErrorLogger\
- Desktop\
--- WindowsApp1\
- Services\
--- WindowsService1\
--- WindowsService2\
- WebApps\
--- WebApp1\
--- WebApp2\
Now, inside each major application I have, for example:
- WindowsService1\
--- WindowsService1\ (this contains all *.cs, bin, obj, etc and .csproj file)
--- Solution\ (this contains the .sln file where you link to other projects like ErrorLogger, etc)
I hope that makes sense!
"First off, let’s agree that namespace should match folder structure and that each language artifact [sic] should be in its own file."
Funny, that's how packages work in Java. I always thought that breaking the link between namespaces and directory structure was considered one of the improvements that C# introduced. Is that not true? (Forgive my ignorance, I'm a Java person.)
I prefer a flat structure with projects in the root.
Inside of these I have various folders and namespaces. I only create different assemblies for deployable units. Small apps won't even have this amount of separation. IMO this keeps things simple. If I ever decide that code I have needs to be used elsewhere, it's easy enough to break it into an assembly if needed, as long as I've followed good namespacing practices.
If you use the nested projects you run the risk of hitting the windows MaxPath issue. This is a huge deal breaker for ever using nested structures. Just imagine meeting this little Gem half way though a dev project, having to name VS projects with 3 letter acronyms just so as not to hit MaxPath. An MS bug ending up as the inspiration for the names of your assemblies. What a joke that would be. Working with a flat structures is much better all round.
-SouceControlFolderName
-Project1
-Src
-Main
-Company.Project1.AppName
*Company.Project1.AppName.sln
*Company.Project1.AppName.Tests.sln
-Company.Project1.AppName.Common
-Company.Project1.AppName.Common.Tests
-Company.Project1.AppName.Entities
-Company.Project1.AppName.Entities.Tests
-Company.Project1.AppName.Security
-Company.Project1.AppName.Security.Tests
-etc.
You could create a separate directory for the test projects or as above and have them all together which is easier to manage when adding to source control i.e. Subversion (TFS is better in many ways save for the fact it needs Explorer integration not just VS integration and a proper off-line story)