How to use two versions of the same DLL in the same project
When using 3rd party libraries, sometimes they let out a new version. And sometimes that new version breaks something that used to work in the old version, but also adds features you need. So you found yourself having to use one method from the old version and another from the new version of the same library.
There are two problems here:
- It won't compile. Both libraries have the same namespace, causing ambiguity the compiler can't handle.
- It won't run. The referenced DLLs are copied to the output dir, but because they have the same name, they will override each other, and will cause the runtime loading of the assembly to have a version mismatch.
Welcome to DLL hell.
Let's take my client's project as a practical example.
The project was using a 3rd party library by Winnovative Software, for handling pdf operations.
The new version of the dll broke some specific functionality that had to be supported.
The DLL name:
The old version: 14.2
The new version: 14.5
The solution has two parts:
- Solve compilation ambiguity with extern alias
- Solve runtime loading ambiguity with
Create a folder for the old DLL, let's say
wnv-old, and put it there.
Add a reference to the old DLL.
Every reference we add to the project will have the "global" alias by default.
For this duplicate reference we'll change the alias so we can differentiate the namespaces.
In the reference properties in Visual Studio, change the alias field to
oldVer or whatever you want:
Wherever we use the namespace we'll change the using statements to:
extern alias newVer; // Must be at top of file using newVer::Winnovative; // Instead of using Winnovative;
And in classes in which you want to use the old version:
extern alias oldVer; using oldVer::Winnovative;
This will make the code compile. Now for solving the runtime crash:
In cmd, use the
sn -T command:
sn -T wnvhtmltopdf.dll Microsoft (R) .NET Framework Strong Name Utility Version 4.0.30319.0 Copyright (c) Microsoft Corporation. All rights reserved. Public key token is b12703d35a33ff98
<runtime>, add a
<codeBase> tag for each version of the DLL. This will resolve the runtime assembly loading conflict.
<dependentAssembly> <assemblyIdentity name="wnvhtmltopdf" publicKeyToken="b12703d35a33ff98" culture="neutral" /> <codeBase version="188.8.131.52" href="DLL\wnv-old\wnvhtmltopdf-old.dll" /> <codeBase version="184.108.40.206" href="DLL\wnvhtmltopdf.dll" /> </dependentAssembly>
That's it, now we can use both versions as we please.
This is a cross-post from my blog