Sharing code across projects

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Jeff Dege

    Sharing code across projects

    I'm working with a group that's been doing C++ coding for quite a long
    time, now, and in that environment we've pretty much worked out
    development practices that serve us well.

    We've been doing more and more, over the last few years, in C# and
    ASP.NET. Some web apps, some background services.

    In our C++ code base, we have a fair number of statically-linked
    libraries that contain code we share between projects. At this point, in
    our C# code, we have only separate files in each project containing
    similar code.

    We would like to move those separate files containing similar code in
    each project to single files shared between projects, the way we have
    been doing with our statically-linked libraries. We just haven't quite
    figured out what is the best way of doing it.

    What would seem most obvious is simply to create DLL projects for each of
    our shared class collections, and to reference the DLLs in the main
    projects. The problem is that the main projects have different release
    schedules. Each would have to ship with different versions of the shared
    DLLs. That means, of course, that we'd need to create a tag in version
    control on every shared DLL for every release. No big deal. We'd have
    to do the same with statically-linked libs.

    But to complicate things, we have some customers who have multiple
    projects installed. And that means that we will have customer machines
    with different versions of the shared DLLs installed for different
    projects. And that's when our support staff starts to scream.

    Is there a way of sharing code between projects so that it ends up in a
    single assembly, instead of requiring separate DLLs? Someone recommended
    using the "Add as Link" option of "Add Existing Item", but I'm not sure
    that really addresses the problem I'm talking about, and it doesn't seem
    to work in Web Apps anyway, and we need a solution that works in both.

    (You can assume that we will have some classes that will be shared across
    all web apps, some classes that will be shared across all non-web apps,
    and some classes that will be shared across all apps, web and non-web
    both.)

    Any ideas?

    What should I be looking at?

    --
    Freedom is not empowerment. Empowerment is what the Serbs have in
    Bosnia. Anybody can grab a gun and be empowered. It's not entitlement. An
    entitlement is what people on welfare get, and how free are they? It's
    not an endlessly expanding list of rights - the 'right' to education,
    the 'right' to health care, the 'right' to food and housing. That's not
    freedom, that's dependency. Those aren't rights, those are the rations
    of slavery - hay and a barn for human cattle.
    -- P.J. O'Rourke
  • Mark Rae [MVP]

    #2
    Re: Sharing code across projects

    "Jeff Dege" <jdege@jdege.vi si.comwrote in message
    news:n66dndajWq jNyLbVnZ2dnUVZ_ rvinZ2d@posted. visi...
    What should I be looking at?
    Any source control software will do this:




    --
    Mark Rae
    ASP.NET MVP


    Comment

    • Jeff Dege

      #3
      Re: Sharing code across projects

      On Wed, 14 May 2008 22:24:08 +0100, Mark Rae [MVP] wrote:
      "Jeff Dege" <jdege@jdege.vi si.comwrote in message
      news:n66dndajWq jNyLbVnZ2dnUVZ_ rvinZ2d@posted. visi...
      >
      >What should I be looking at?
      >
      Any source control software will do this:

      http://msdn.microsoft.com/en-us/team.../aa718934.aspx
      We've thought about that, but we're not certain how to handle merging of
      release branches.

      Suppose project A depends on library C. When we're ready to ship version
      3.1 of project A, we create a A_3_1 branch on library C. After A ships,
      we continue development on other projects, and library C continues to
      change.

      Now suppose we have to go back and make changes to project A, and some of
      those changes will need to be made in the library C code. We have two
      choices - we either move the version of library C that is used in project
      A forward to the most current version, and then make any changes that
      need to be done for project A, or we make our changes on the A_3_1 branch.

      Most of the time we will do the former. But we need the ability to do
      the latter. And when we do need to do the latter, we also need the
      ability to merge the changes we made on the A_3_1 branch into the main
      stream of development.

      This kind of thing is confusing enough to keep straight when you have
      named releases, and an independent release history, for your shared
      library. Trying to keep it straight absent that is almost certainly an
      exercise in futility.

      From Robert Martin:



      The Reuse/Release Equivalence Principle (REP).

      THE GRANULE OF REUSE IS THE GRANULE OF RELEASE. ONLY COMPONENTS THAT ARE
      RELEASED THROUGH A TRACKING SYSTEM CAN BE EFFECTIVELY REUSED. THIS
      GRANULE IS THE PACKAGE.

      Reusability is one of the most oft claimed goals of OOD. But what is
      reuse? Is it reuse if I snatch a bunch of code from one program and
      textually insert it into another? It is reuse if I steal a module from
      someone else and link it into my own libraries? I dont think so.

      The above are examples of code copying; and it comes with a serious
      disadvantage: you own the code you copy! If it doesnt work in your
      environment, you have to change it. If there are bugs in the code, you
      have to fix them. If the original author finds some bugs in the code and
      fixes them, you have to find this out, and you have to figure out how to
      make the changes in your own copy. Eventually the code you copied
      diverges so much from the original that it can hardly be recognized. The
      code is yours. While code copying can make it easier to do some initial
      development; it does not help very much with the most expensive phase of
      the software lifecycle, maintenance.

      I prefer to define reuse as follows. I reuse code if, and only if, I never
      need to look at the source code (other than the public portions of header
      files). I need only link with static libraries or include dynamic
      libraries. Whenever these libraries are fixed or enhanced, I receive a
      new version which I can then integrate into my system when opportunity
      allows. That is, I expect the code I am reusing to be treated like a
      product. It is not maintained by me. It is not distributed by me. I am
      the customer, and the author, or some other entity, is responsible for
      maintaining it.

      When the libraries that I am reusing are changed by the author, I need to
      be notified. Moreover, I may decide to use the old version of the library
      for a time. Such a decision will be based upon whether the changes made
      are important to me, and when I can fit the integration into my schedule.
      Therefore, I will need the author to make regular releases of the
      library. I will also need the author to be able to identify these
      releases with release numbers or names of some sort.

      Thus, I can reuse nothing that is not also released. Moreover, when I
      reuse something in a released library, I am in effect a client of the
      entire library. Whether the changes affect me or not, I will have to
      integrate with each new version of the library when it comes out, so that
      I can take advantage of later enhancements and fixes.

      And so, the REP states that the granule of reuse can be no smaller than
      the granule of release. Anything that we reuse must also be released.
      Clearly, packages are a candidate for a releasable entity. It might be
      possible to release and track classes, but there are so many classes in a
      typical application that this would almost certainly overwhelm the
      release tracking system. We need some larger scale entity to act as the
      granule of release; and the package seems to fit this need rather well.


      --
      It is not from the benevolence of the butcher, the brewer, or the baker
      that we expect our supper, but from their regard to their own interest.
      - Adam Smith, "The Wealth of Nations"

      Comment

      Working...