7

In my every-day work solution we have 80 projects circa. This solution contains 4 different web-sites, the business logic and the infrastructure assemblies (such as extension methods, various utilities, repository base classes and so on).

The solution works quite good but if we add the test projects to the solution we easily pass over 100 projects which makes working with this solution very tedious.

In my search for a solution, I got really interested by Nuget and I started wondering if it can help us.

The idea would be to split the huge solution into smaller atomic pieces whose output would be a Nuget package to be uploaded to a private Nuget repository.

The web-sites will be referencing the packages other than a class-library bound to that specific web-site.

From the CI point of view:

Each package solution should be atomic.

  • It should be able to fetch its references (other NuGet packages, both from the official feed and the private one);
  • Build
  • Run its tests
  • Assemble a package
  • Upload the new package to the repository

The product solutions (say the web-sites) should be build after:

  • A commit of their code
  • An update of the NuGet packages on the private repository

Any suggestion? Or maybe a better way to achieve the split of this huge solution?

Kralizek
  • 1,999
  • 1
  • 28
  • 47
  • 2
    I'm interested in knowing how well did it go with this approach. I'm facing a similar problem in a slightly bigger scale (+400 projects, including C#, C, C++ and managed C++). I hope this approach can also help reducing build time costs. What was your experience? – Fede Aug 16 '13 at 19:15

2 Answers2

7

Using package management (on Windows: NuGet) is certainly a solid approach here. You get dependency resolution 'for free' and can take advantage of semantic versioning for communicating meaningful information to package consumers merely through the package version number.

However, NuGet is in effect a specific implementation of some more fundamental patterns:

  1. Only build code that has changed
  2. Decompose systems into small, manageable units
  3. Do not build 'frameworks'

From your question, it sounds like you are building more code than necessary, and that your code is less modular than it could be. Using NuGet to modularise your code will help to implement these three patterns (certainly 1 and 2 - you'll need to take additional steps for 3).

Applying these patterns will help @Fede too (for whom - with C and C++ code - NuGet is not applicable). Generally, by making your software more modular (yet avoiding the trap of building a monolithic, all-knowing 'framework', usually called *.Library.dll, or *.Common.dll, etc.) you will achieve better build architecture.

Ultimately, each 'chunk' of code (Project or Solution in Visual Studio terms) should be comprehensible to a single developer; if it's too unwieldy or complicated, split it up. Projects, Solutions, .cs files, etc. are all abstractions for humans, not for machines, so the size and relationship between them should reflect our human abilities and need for understanding. Taking that too far will lead to the need to change multiple packages to complete a single feature: in this case, the separation by definition is to granular, and you'll need to re-group some code together again.

(Disclosure: I am the co-author of Windows Package Management - PackageManagementBook.com)

Matthew Skelton
  • 2,220
  • 21
  • 21
0

You could probably move each individual website to a different solution. If you are using a version control tool, this would probably be a logical step, because each individual project would be versioned individually, meaning a developer would not have to synchronize with all projects at once. Also, individual websites should be independent from each other, so it shouldn't be a troublesome move.

Do you have generic or common code that's not tightly related to a specific "business project"? This code could be moved to another solution, like a company framework or something similar. Each business project would then use a released version of the framework, upgrading only when and how it seems logical to do business-wise. For example, if Website A is currently on a tight release schedule, it might not be a good idea to introduce a version of the framework that includes breaking changes. However, if Website B is in a non-critical phase, you might want to include new features from you framework and deal with breaking changes while you have a little slack time.

I don't know if it's possible to satisfy your requirements with NuGet, but Atlassian offers some tools (namely, FishEye, Crucible and Bamboo) that could help you achieve something like this in an organized way. Note: I'm not affiliated with Atlassian.

Benjamin Beaulieu
  • 995
  • 2
  • 10
  • 26