Structuring your .NET solution on the file system

This is probably a subject at the same level of controversy as the one about where to put those pesky curly braces but let’s try setting personal preferences aside and look at it in an objective way.

It’s a fact that developers love consistency or at least in my opinion if they don’t then it is a disqualifying criteria in any job interview. However, another thing that developers tend to love is their own sense of consistency, basically they love being consistent in the way they like the best so it is important to pick one approach and make everyone stick to it.

When it comes to structuring a .NET solution in the filesystem I generally see two approaches being used:

  1. Hierarchical;
  2. Mostly flat.

In the first one its typical to see each part of a project name map to a physical folder, in this scenario, for Contoso.Web.Controls.[cs|k]proj you would expect to find the code in Contoso\Web\Controls\ path. In the mostly flat camp, the code for the previously mentioned project would be found at a folder named Contoso.Web.Controls\.

I’m in the mostly flat camp because I value that the number of parts in a project name does not affect the level at which it will be physically located. This tends to simplify things a lot when it comes to working with the filesystem structure either in build scripts or just for setting common output folders.

Another reason in favor of the mostly flat structure is that it aligns best with what we see more in the .NET open source community, see EntityFramework or ASP. NET MVC. This second part is specially important now that .NET itself made significant steps to become an open source framework.

Couple this second approach with the structure proposed by David Fowler and you have a quick set of rules that will allow you to be consistent within your project while at the same time following the overall trend in the .NET ecosystem.

A Different Kind of Assembly Hell

An assembly is first and foremost a deployment unit, they should normally be used to group code that works together and is deployed together or putting it the other way around, they are used to split code that may not be deployed together.

There are reasons to split code between multiple assemblies even if you intend to deploy them together but these are exceptions to the rule. I would see independent versioning requirements as one possible exceptional reason.

What you really shouldn’t do is create assemblies just for the sake of splitting your code for cosmetic reasons. I’m not saying that you shouldn’t organize your code, just saying there are better tools for that job. In this case, that would be namespaces alongside project folders and while on the subject of namespaces, another thing that really does not make any sense is to try to have a single namespace per assembly. If you’re down that path, take a step back cause you’re doing it wrong…

I saw, more than one time, .NET solutions suffer from this assembly explosion and quickly escalating to the hundreds of assemblies for something that it sure as hell wasn’t that complex and where 80% of the assemblies end up being deployed together due to a high level of dependencies.

However, you also need to avoid doing the opposite and cram everything in a single assembly. As pretty much everything in software development the correct answer depends on many things specific to the scenario at hand.

Be conscious of your decisions and why you make them.