Merge redundant assemblies

Lately I have become a big opponent of a popular anti-pattern: people insisting on splitting up their application tiers/layers into 5-10 separate Visual Studio projects and adding references between them. Double that number of projects if you want corresponding unit test project for each layer.

In fact, removing them has become one of the first steps I take when inheriting a legacy code base. If I were writing a book on refactoring Visual Studio solutions, I would call it Merge redundant assemblies. Here’s a diagram:

You don’t need to split your code across 50 gazillion projects. Next time you think of creating a new project in your solution, please remember the following:

  • Visual Studio projects are for outputing assemblies. Namespaces are for organising code.
  • Assemblies only need to be split if your deployment scenario demands it. Putting a client API library into a separate assembly makes sense because the same API assembly may be used between many apps, or in different App Domains. Deploying your domain model or data layer into a separate assembly does not make sense, unless other apps need them too.
  • Each additional project slows down your build. A giant project with hundreds of classes will compile faster than a smaller number of classes split amongst multiple projects.
  • Crossing assembly boundaries hurts runtime performance. Your app will start up slower, the ability to perform inlining and OS optimization is reduced, and additional security overhead is enforced between assemblies. Assemblies are supposed to be big and heavy; loading lots of little one goes against the CLR.
  • You don’t need one test project for each assembly. One giant tests project is normally fine. The only case I have seen where it made sense to have separate test projects was for a client API which duplicated many of the server internal class names and we wanted to avoid overlap/namespace pollution.
  • Common sense should be used to enforce one-way dependencies. Not assembly references.

Patrick Smacchia has a good list of valid/invalid use cases where separate assemblies are appropriate here.

August 16, 2010

4 Comments

Neal Blomfield on August 16, 2010 at 11:42 pm.

All good points, my current solution has a code project, a web project and 3 test projects because it was easier to manage different test types in different assemblies – unit, integration, acceptance.
The key thing with using namespaces to organise code is to organise around features rather than layers as it makes the code related to a single feature easier to find / manage. I didn’t do this and now I am regretting that choice.

Joshua Lewis on August 17, 2010 at 6:40 am.

I agree completely with Neal, I use namespaces for features and not for layers.

Good post, confirms some of my thoughts. Thank you

Stacey on March 20, 2011 at 2:42 pm.

This is a very good article. I find myself falling into this trap a lot, too – trying to separate my ‘layers’ based on isolating them, rather than the need to. I thought I was pretty smart when I designed a Web/Models/Persistence project setup and then began to realize that decoupling is not 100% possible.

I found I spent more time trying to avoid adding references to my Domain Layer than I did actually getting code written. I thought that keeping my Models anemic was purporting the Separation of Concerns principle, but in reality I was just making my code more abstract than it needed to be.

Leave a Reply