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.
The problem
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.
The solution
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: wnvhtmltopdf.dll
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
Place old DLL in folder
Create a folder for the old DLL, let's say wnv-old
, and put it there.
Add a reference to the old DLL.
Solve compilation ambiguity with extern alias
Change the reference aliases:
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 newVer
and oldVer
or whatever you want:
Change the using statements:
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:
Get DLL publicKeyToken
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
Modify app.config / web.config
Under <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="14.2.0.0" href="DLL\wnv-old\wnvhtmltopdf-old.dll" />
<codeBase version="14.5.0.0" 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
Top comments (0)