views:

88

answers:

1

As an ISV company we slowly run into the "structure your code"-issue. We mainly develop using Visual Studio 2008 and 2010 RC. Languages c# and vb.net. We have our own Team Foundation Server and of course we use Source Control. When we started developing based on the .NET Framework, we also begun using Namespaces in a primitive way. With the time we 'became more mature', i mean we learned to use the namespaces and we structured the code more and more, but only in the solution scope. Now we have about 100 different projects and solutions in our Source Safe. We realized that many of our own classes are coded very redundant, i mean, a Write2Log, GetExtensionFromFilename or similar Function can be found between one and 20 times in all these projects and solutions.

So my idea is:

Creating one single kind of root folder in Source Control and start an own namespace-hierarchy-structure below this root, let's name it CompanyName. A Write2Log class would then be found in CompanyName.System.Logging. Whenever we create a new solution or project and we need a log function, we will 'namespace' that solution and place it accordingly somewhere below the CompanyName root folder. To have the logging functionality we then import (add) the existing project to the solution. Those 20+ projects/solutions with the write2log class can then be maintained in one single place.

To my questions: - is that a good idea, the philosophy of namespaces and source control? - There must be a good book explaining the Namespaces combined with Source Control, yes? any hints/directions/tips? - how do you manage your 50+ projects?

+1  A: 

Here's how we do it (we're also an ISV, and we use TFS):

We have an in-house framework that all of our products use. The framework includes base classes for our Data Access Layer, services like logging, utility features, UI controls, etc).

So, we have a Team Project for our framework: Framework\v1.0\Main\Framework

(note the repetition of "framework", looks weird, but it's important)

Then we have a Team Project for each product, and we branch the framwork into the team project:

ProductName\v1.0\Main\ProductName

ProductName\v1.0\Main\Framework (branched from \Framework\v1.0\main\Framework, we make this branch read-only)

any code under "\Main\ProductName" can reference any code under\Main\Framework

Further, if we need to create working branches of our product, we just branch at "Main" like so:

ProductName\v1.0\WIP\MyBranch\ (branched from Main, where MyBranch == Main)

That gives us 2 really cool features:

  1. I can create branches without messing up my references as long as I keep everything below "Main" together. This is because VS will use relative paths to the references, and as long as I keep everything below Main together (and I do NOT reference anything "above" main, the relative paths remain intact.

  2. If I update the "real" framework (under \Framework\v1.0)), I can choose for each product when I want to merge those framework updates into the product's code base.

(that's really useful if you use shared libraries, because it decouples internal releases of your shared framework from external releases of your products). If you are just moving to shared libraries, one of the problems you are going to encounter is "collisions", where a change to your shared code mandates changes to your product code in order to stay compatible. By branching your shared code, you can update your framework without immediately impacting all of your products at the same time.

JMarsch
(BTW): the framework code is in distinct assemblies, so when MyProduct references something in framework, it's through Project References in our solution.
JMarsch
first, many thanks, JMarsch. we've never used the branching feature, but we will have a look at that one for sure. Then i'll try to setup an environment which matches exactly your description.I'll post my results here.. as soon as there are any ..
Christian
Glad to help! We use some additional branches as well: we can create a v1.1, 2.0 etc to allow for developing the next release while still maintaining the shipping version (v1.1 would get a new branch, but v1.0.1 is just merged into main of the v1.0 branch). We also create an \Archives branch (at the same level as Main), where we keep a frozen copy of all releaeses and milestones (betas, release 1.0.1, release 1.0.2, etc) That allows us to recreate the code exactly as it was for any version that we ever shipped.
JMarsch