Supporting Two Simultaneous Versions of a NuGet Library...Maybe

Or, Stupid Tricks with NuGet!

I had a situation a few months back where I needed to use two different versions of Entity Framework -- version 4.1 and version 6 -- within the same application. This was due to accessing two separate data sources, one of which was made with Entity Framework Code First. The part that depended on EF v4.1 was a third-party schema and access library, and converting to EF v6 would have been prohibitive even though the source was available. And of course, being a Code First database, EF would complain if any version other than v6 was used to access the other database.

In most cases here, I would be SOL. EF v4.1 and v6 are not API compatible, and the NuGet tools (inside of Visual Studio) will only let you reference one version of a library per project, although you can have more than one version referenced within a solution.

Papers, Please

There is a wonderful game called Papers, Please where you play as a border agent for a fictional Soviet-bloc-type country named Arstotzka, and your job is to check passports for validity and grant or deny entry into the country.

During the game, you encounter this amazing character named Jorji Costova. The first time he appears he doesn't have a passport, and naturally you are supposed to turn him away. A little while later, he returns with a clearly hand drawn fake passport. This continues throughout the game, and each time he returns his attempts to make his way past the border check grow more and more ludicrous.

Why do I bring this up? Because the way I found around NuGet's constraints with versions feels a little bit like Jorji. NuGet would normally deny what I wanted to do, so I decided to try to fake it out.

I manually added a reference to both library versions in the packages.config file and see whether NuGet could handle it. So my file looked similar to the following (with the unecessary bits ...'d out):

<?xml version="1.0" encoding="utf-8"?>
    <packages>
    ...
    <package id="EntityFramework" version="4.1.10331.0" targetFramework="net45" />
    <package id="EntityFramework" version="6.0.2" targetFramework="net45" />
    ...
    </packages>
</xml>

Lo and behold, running package restore after the changes worked and NuGet happily added references to both library versions to my application!

Why This Typically Won't Work

Now I need to qualify this case with a "you really shouldn't be trying this." The only reason why I can actually use the two different version of EF in my application are because v4.1 and v6 use entirely different namespaces with no overlap. Otherwise, there would be type collisions galore.

For reference, the types used in EF v4.1 exist under System.Data, whereas the types in v6 exist under System.Data.Entity. For more details on the differences between older and newer versions of EF, check the upgrade guide for Entity Framework available on MSDN.

So as far as I can tell, this trick will only work in situations where the different versions of the library would not have any type collisions. If that happens to be true, then you could theoretically include as many versions of a library as you want. In the majority of cases however, you (and I) would probably do the work to update the code to work with the latest version of a library that is required.

Anyway, if you do this and horrible things happen that cause loads of downtime and significant losses of data, don't say I didn't warn you!