views:

221

answers:

7

Okay, so here's the scenario.

Project A has a class library developed for it (lets call it MyLib). I release project A (in house project) with version 1 of MyLib.

I begin development on Project B, but expand MyLib to version 2, including a few optimizations to existing types.

If I release Mylib 2 to both Project A and Project B, I'm going to have to recompile Project A to support type changes, does anyone have solutions to this that are tried and true?

+4  A: 

You can try assembly redirection and have Project A load the newer version of your library. This would require that you add the redirect information to the configuration of all the machines that the application is run on but you wouldn't have to re-compile. You could do this in the application configuration file or at the machine level.

An example from that article of what the file would look like:

<configuration>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="myAssembly"
          publicKeyToken="32ab4ba45e0a69a1"
          culture="en-us" />
        <bindingRedirect oldVersion="1.0.0.0" newVersion="2.0.0.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>

Of course, if you broke compatibility with your original library in the new version this isn't going to work.

Steven Lyons
reasonable answer but i'm wondering if i have other options.
Firoso
I used binding redirects in a previous company. Have to say there were nice and easy to use, although you do obviously get a large build up with many revisions. One of the useful features though is its quite easy to provide an update mechanism that can also roll back by removing old redirects.
Ian
+3  A: 

If you don't like @Steven's direction of assembly redirection, and assuming you DON'T want to recompile Project A, you can just privately deploy different versions of MyLib to each project.
Project A would then just continue to use version 1, and Project B would use version 2. This seems to be what you are wanting to hear - and it is trivial to do. Either put the MyLib dll in each project's folder (or subfolder) and each project will automatically pick up the respective local version, or you can strongname them in the GAC, and have each project pick up the specific version you compiled against.
This is actually the default behavior, and you don't need to do anything complex to achieve this.

AviD
+3  A: 

Give MyLib a strong name and install it to the GAC. The GAC can have multiple versions of the same assembly. It would require giving a strong name to version 1 of MyLib (not just version 2).

Project A wants version 1 of MyLib and finds it in the GAC. Project B wants version 2 of MyLib and finds it in the GAC. Everybody is happy, and you don't have to keep 30 copies of different versions of MyLib in the same directories of the assemblies that use them, recreating DLL-hell.

I know that AviD mentioned the GAC as well, but as an alternative to private copies for the executables. I think that should be avoided.

Joel B Fant
Though the GAC is often a good solution, best practice is NOT to put your assmeblies in the GAC unless you have a good reason. Though this situation (and versioning in general) may be sufficient reason to do so, in any event strongly consider otherwise.
AviD
@AviD: I agree that it is something to be decided based on the situation at hand. I just think micro-managing what version of the library is in each folder adds points of failure. If the number of installations in-house was anything but small or the number of applications using the library was anything but a handful, local copies would not be my first choice.
Joel B Fant
@Joel, agreed - depends on scope of sharing.
AviD
A: 

Here's another option, though you should seriously consider the other options first.

ProjectA references MyLib.dll, which happens to be version 1.

Adjust the output name of the MyLib project to produce "MyLib.2.dll". (You could also create a new project, but that sounds like overkill.)

Rebuild MyLib and ProjectB. ProjectB will now reference MyLib.2.dll, leaving ProjectA and MyLib.dll completely unaffected.

John Fisher
+1  A: 

My suggestion: Continuous Integration.

Using a tool like CruiseControl.NET you could do a rebuild of every project/solution there is, even have the output of one (the .dll) uploaded to Source COntrol to be used by other projects, have unit tests run every time so you can check if additions / edits in a project used in solution A does not break Solution B also using that project. You could set the build to automatic every night or trigger one manually from the CruiseControl.NET systray app.

Colin
This is the most helpful response for me.
Firoso
A: 

Your question is quite general. What do you want to achive? Should Project A use version 2 of your lib or the old version?

If A should use version 1, then strong naming or privat deployment should solve your problem. But I think then you whould not had asked the question.

If A should use version 2, then the solution depends on your changes. If the interface of the assembly has not changed (but only internals algorithms) then A should work with V2 without recompilation. If the interface has changed, you will have to adjust project A anyway and there cannot be a general solution.

To keep required changes small an managable is a question of good object/interface design. But how to do that cannot be answered without details about your objects and required changes.

Achim
A: 

I would put all of my code in a version control like Subversion ( use of branches and tags ) and automate the build process. I use FinalBuilder.

Because you have control over the library i would recommend release branches pattern .

ErvinS