Quite often we want to create a solution that have a root namespace and also creates assembly names that match this. It keeps things tidy and also means that if, for example, your solution is packaged to be used in other solutions then the namespace reflects its purpose.
Now, have you ever opened a solution and found it structured somewhat like this?

The first problem is that it takes a while to find the project that you need to work on. We can organise it into solution folders which will help.

Solution folders don't physically map to file system folders, which can be quite frustrating as it means that the file system structure is untidy too. After restructuring the file system as well it's a lot tidier.

This is better, but we still have two issues:
- It's still really hard to read the purpose of each project as it's at the end of the project name.
- We have really long file paths. By default Windows stores solutions in
C:\Users\(UserName)\source
but this can be changed. As I have multiple accounts on Github and Azure DevOps I useC:\source\(Github|AzureDevOps)\(AccountName)\
which makes it somewhat longer. The maximum path length in Windows in 260 characters. The pathC:\source\GitHub\PaulCodesStuff\AcmeWidgetCompany\src\Application\AcmeWidgetCompany.Application.Messaging
is already 105 characters without any other folders and files.
N.B. You can enable longer file paths in Windows by editing the registry. However Visual Studio will still not support them.
We can rename the project folders that are created, e.g. AcmeWidgetCompany.Application.Messaging to Messaging, but this requires either removing the project from the solution and then adding it back in after the rename or closing the solution, renaming and then manually editing the solution file. This will need to be done whenever new projects are added as Visual Studio always uses the full project name for the folder.
Solution 1 - Project Level Override
We can create a class library called 'Abstractions', right click on it and click properties, and then manually override the assembly name to AcmeWidgetCompany.Domain.Abstractions
, or better still, AcmeWidgetCompany.Domain.$(MSBuildProjectName)
. The same can then be done for default namespace (noting spaces are replaced with underscores) as shown below:

This is time-consuming and requires discipline when working as a team. It's very easy for this to get overlooked.
Solution 2 - Using Directory.Build.props
The Directory.Build.props
file instructs MSBuild to override default property settings at folder level. By placing one in the \src
folder with the following content we can tell MSBuild that the assembly name should be prefixed with AcmeWidgetCompany
. Visual Studio also uses this file to determine the default root namespace for files within the folder.
<Project>
<PropertyGroup>
<RootNamespace>AcmeWidgetCompany.$(MSBuildProjectName.Replace(" ", "_"))</RootNamespace>
<AssemblyName>AcmeWidgetCompany.$(MSBuildProjectName)</AssemblyName>
</PropertyGroup>
</Project>
Now, as long as we don't override these at project level, all of our projects will be automatically prefixed with 'AcmeWidgetCompany'.
So our solution now looks like this:

And our file system can be arranged like this:

This has already made things more readable, however we can go further. As the Directory.Build.props
file works at folder level, we can add separate ones to the Domain, Application, Infrastructure, Persistence and Presentation folders. We can also add ones to Messaging and Payments within the Infrastructure folder. In this example we only have a single project, without any prefix, in the Presentation and Persistence layers, so we'll miss these out for the time being. We can refactor at a later date if necessary.

Mirroring this on the filesystem:

Conclusion
We can use Directory.Build.props as a simple way to prefix namespaces and assembly names at folder level. Doing so helps to keep the solution tidy and easier to navigate. It also helps us to limit the length of the file path which can be an issue on Windows based systems.
I recommend the Directory.Build.props option in preference to changing the project properties. In large solutions it requires less work and discipline from a team.
The two solutions above are available on Github.