How Do You Deal With Common Infrastructure Code For Multiple Projects?

December 2nd, 2008

Here’s the situation: a couple of months ago we started developing according to a new architecture. Obviously, you need infrastructure code for this. For the first project, we just put the infrastructure code into the project’s solution and everything was easy. We could make changes as we needed them, and it enabled us to ‘grow’ the infrastructure into what we really needed. Then came the second project. I was reluctant to extract the infrastructure code in a separate reusable assembly because i felt it would lead to less flexibility to make changes. So i copied the infrastructure classes into the new project. Obviously, some changes were made in the classes of the second project, which weren’t ported to the classes of the first project. Add another project or two, and you can see the problem :)

So now we’re trying to figure out how best to move forward. I’ve got 3 options in mind:

  1. Infrastructure code as a separate project, binary ‘framework’ dependency per ‘client’ project
  2. Infrastructure code as a separate project, ‘framework’ dependency (in source form) per project (as in: copying the code of a specific version of the ‘framework’ into the project’s own repository)
  3. Each project just contains the infrastructure code in their own project and there is no specific ‘framework’

The way i see it, each approach has its pro’s and con’s:

  1. Infrastructure code as a separate project, binary ‘framework’ dependency per ‘client’ project
    • Pro’s
      • The code only has to be maintained in one place
      • Everybody can benefit from changes
    • Con’s
      • Can make debugging harder because you can’t step into the framework code
      • Requires a lot of discipline for versioning and distributing updates to ‘client’ projects
      • The infrastructure code has to have a lot of extensibility points so each application can add extra functionality


  2. Infrastructure code as a separate project, ‘framework’ dependency (in source form) per project (as in: copying the code of a specific version of the ‘framework’ into the project’s own repository)
    • Pro’s
      • Does not have the debugging issue
      • Code only has to be maintained in one place (in theory)
      • Everybody can benefit from changes
    • Con’s
      • The infrastructure code has to have a lot of extensibility points so each application can add extra functionality
      • If people change the infrastructure code in their project, all changes should be sent upstream to the ‘real’ infrastructure repository, or extension points need to be provided in the original infrastructure code so upgrades of the infrastructure library still offer the same possibilities for the specific project
      • Still requires versioning discipline, although it probably wouldn’t need to be as strict as with Option 1


  3. Each project just contains the infrastructure code in their own project and there is no specific ‘framework’
    • Pro’s
      • Highly flexible… each project can freely make changes to make the infrastructure behave exactly as it needs to for the project
    • Con’s
      • Leads to multiple ‘versions’ of many of the classes… when a new project starts, which versions of each class should be used?
      • Starting a new project contains boring set-up work which is basically just copy/pasting existing classes from previous projects

The reason i’m posting this, is because i’d love to get your feedback on this… what other pros/cons can you think of for each approach? Which approach would you recommend? Is there another approach we haven’t thought of?

Guest Blogger Esoterica

  1. Karsten
    December 3rd, 2008 at 02:28 | #1

    Sorry, but I don’t quite understand the options you mention.

    Option 1) Do you mean that
    The infrastructure code is in a project on it’s own, you build it. And in your multiple solutions, you add a reference to the build assembly?

    Option 2) Do you mean that
    The infrastructure code is in a project on it’s own, but you include the project and source in your multiple solutions and build the infrastructure with the rest of your solution?

  2. December 3rd, 2008 at 02:29 | #2

    @Karsten

    yes and yes :)

  3. Laila
    December 3rd, 2008 at 06:16 | #3

    I’d go for option 1.
    You could set up a source server to avoid the debugging problem.

  4. December 3rd, 2008 at 10:49 | #4

    @StevePy: “I prefer more of a common component library or service provider approach.”

    We started off looking at the Global Application Framework To End All Frameworks but quickly realized that this wasn’t going to be productive – and instead changed that into a collection of common library components, minimizing or removing dependencies on each other. So you can pick and choose the components a la carte as suitable for the project. For example, assemblies for Windsor or for Spring.Net.

    This reduces (but does not eliminate) one of your Cons for option 1 – “The infrastructure code has to have a lot of extensibility points “.

    It also helps with a problem of the Global Framework – you have Project X that could use 99% of whats in the GloboFramework, but due to one little thing like they use a slightly older build of NHibernate, you can’t include the GloboFramework dependencies at all.

  5. December 4th, 2008 at 08:27 | #5

    If you go with option 1, there is a quick way to debug the framework code. Whenever you want to step into framework code, simply overwrite all of the framework’s Release output (in bin/Release) with the Debug output (from bin/Debug). This way, you don’t have to make any reference path changes in your projects and you can still benefit from debugging.

    It is entirely possible that this only works because of the way we reference our common code: ‘client’ projects reference the build output of our common code. We don’t check the binaries into source control, so it means each developer has to build the common project. This, however, comes with its own bag of issues.

  6. Dave Macpherson
    December 4th, 2008 at 16:51 | #6

    Option 1, clearly. In Java projects, use Maven as the build system, and version different builds of your infrastructure project in your local Maven repository. Dependent projects can specify a dependency on whatever version of the infrastructure project they require in their master POM definition file and everything just works.

  7. Tetsuo
    December 4th, 2008 at 22:03 | #7

    I have the same problem. I still haven’t made a decision, but I’m thinking about this (Java):

    1. Integration code: code to ‘glue’, say, Wicket to Spring to Hibernate. Separate project, new projects just import the binary. Should be minimal and stable. No forks.

    2. Common components: rich components that don’t exists in open source libraries. Separate project, may import (1), new projects import the binary. Grows as time goes, without affecting the core (1). New projects may fork components to adapt them to their contexts, if really necessary.

    3. Common code that is very likely to change: base templates, configuration, css files, etc. Separate project, copied source. If I use Maven as build tool, it may be an archetype (a kind of quickstart code generator).

    This structure keeps the core stable, what makes the chances of breaking stuff lower. Components are shared, but any major flexibility needs are satisfied by forking some code., These components should be kept as much ‘vertical’ as possible, without too much dependencies between them. And, the code that every project has to write again and again (very similar, but tweaked to the specific application) is just copied and never breaks other projects.

    It’s very tempting to just say “Centralize! DRY! Are you stupid or something? It’s so obvious!”, but dependencies and version control is not a problem you can take lightly. And keep ‘one framework to rule them all’ IS a very difficult and painful task. But sometimes necessary. My answer to this is to make this framework as little as possible, to minimize this pain.

    Well, for now, I guess :)

Comment pages
Comments are closed.