16

I recently started out working for a new client with an old legacy codebase in which there are multiple .net solutions, each typically hosts some projects unique to that solution but then "borrows" / "links in" (add existing project) some other projects which technically belongs to other solutions (at least if you go by the folder structure in TFS)

I have never seen a setup this intertwined, there is no clear build order, sometimes a project in solution A just reference dlls directly from the output directory of a project hosted in solution B, sometimes the project has just been included directly even if it resides FAR away in the folder structure.

It looks like everything has been optimized for developer laziness.

When I confronted them with why they didn't have a CI server they responded that it is hard to set up with the code organized like it is. (I'm setting it up now and cursing this code-organization)

The solutions are organized around deployment artifacts (stuff that needs to be deployed together are in the same solution) which I think is a wise decision, but the contents of those solutions (the projects) are all over the place.

Is there a consensus of a best practice to use when reusing common class libraries across multiple solutions / deployment artifacts,

  • How to structure code in the VCS
  • How to facilitate sharing of business logic between separate deployment artifacts
AndreasKnudsen
  • 271
  • 2
  • 5

2 Answers2

9

I have never been a fan of including existing projects that belong to other solutions. There are too many variables where making an edit to that project for 1 solution completely breaks something in another solution. Then by fixing that problem you end up breaking the original solution. Lather, rinse, repeat.

When this kind of dependency leaks into multiple solutions, I like to separate out the dependent code into its OWN solution and create a black-box library that is then included as a reference. My thinking is that your solutions were intertwined so that debugging could be done all the way into the shared project for every solution. If the library is built and tested properly, this kind of debugging really isn't necessary. The library should be able to stand on its own merits and should be tested thoroughly so that the expectations of any consumer project would be met consistently.

Joel Etherton
  • 11,674
  • 6
  • 45
  • 55
  • 3
    In addition, refactoring is so easy these days, so if you *do* feel that some spur-of-the-moment change is important enough to make in the library itself, you can make it your application project *now* and merge it into the library *later*, when you're less distracted by your current task and have time to do proper testing. – Aaronaught Aug 19 '11 at 12:25
  • @Aaronaught: +1 to that. – Joel Etherton Aug 19 '11 at 12:50
5

I have actually organized such TFS structures like the one you are mentioning and while it does present unique challenges to CI it has a number of different benefits. One clear one is it supports and encourages proper componentization into seperate .NET projects and thus supports good TDD by encouraging 100% test coverage. Right off the bat I notice a few problems that you can address.

sometimes a project in solution A just reference dlls directly from the output directory of a project hosted in solution B, sometimes the project has just been included directly even if it resides FAR away in the folder structure.

Binary references to the output of other directories isn't a good approach, and becomes a bad approach when intermingled with project references as well. Try to do one or the other, preferablly changing your binary references to project refercences for consistency at the very least. At this point each Solution can represent a single buildable application or application tier, (Eg. SuperApp.sln, OtherAppServices.sln, OtherAppPresentationTier.sln).

To build ALL projects I recommend creating a Master Solution as well. The Master Solution will have project references to everything and essentially exists for the sole benefit of having a single build command that handles all projects in the application suite. Developers should not use the Master Solution for active development or debugging. This makes assembling the build artifacts a lot easier.

Deployment then can be done with a simple batch, powershell or Perl script. This will essentially build the appropriate solution or the Master solution and then deploy everything to the appropriate environments. This can be easily integrated into any CI server if done right.

•How to facilitate sharing of business logic between separate deployment artifacts

Create a project for common business logic or have better seperation of concerns for more global or universal business logic. All deployable solutions that wish to reference this should do so by a project reference.

In organizing your code in TFS, it becomes easier to achieve this by keeping common or shared projects at a higher level in the directory tree.

maple_shaft
  • 26,401
  • 11
  • 57
  • 131