I have a solution with 2 projects: Proj1 and Proj2, where Proj1 is the startup project.
Proj1 references Proj2 (in order to call Proj2's class) and it has existing code that also references a 3rd party DLL called A, versioned at 1.0.0.0.
Proj2 references the same 3rd party DLL A, but it references it at version 2.0.0.0, since the class in this project needs newer implemenation that was not available in 1.0.0.0.
So far I've tried the following: 1. Switched "Specific Version" to true when referencing A 2. Added a folder called "v2Folder" in Proj2 and added A v2.0.0.0 to it, set its "Copy to Output Directory" to Copy Always 3. Added "probing path" to app.config to point to the sub-folder with the v2.0.0.0 DLL
What I want is to see A v1.0.0.0 in the normal \bin\ folder, and A v2.0.0.0 in \bin\v2Folder, and I expect that when I run my Proj1.exe, Proj1's old code will still call A v1.0.0.0's methods, and only call A v2.0.0.0's methods when calling what is implemented by Proj2.
The problem is, when I build my solution, v1.0.0.0 got replaced by v2.0.0.0, the build log has something like "No way to resolve conflict between "A, Version=2.0.0.0, Culture=neutral, PublicKeyToken=blah" and "A, Version=1.0.0.0, Culture=neutral, PublicKeyToken=blah". Choosing "A, Version=2.0.0.0, Culture=neutral, PublicKeyToken=blah" arbitrarily.".
Can someone help?
config. Under <runtime> , add a <codeBase> tag for each version of the DLL. This will resolve the runtime assembly loading conflict. That's it, now we can use both versions as we please.
Any DLL that lays somewhere in file system can be referenced. After compilation this DLL must be either in GAC (Global Assembly Cache) or in same directory with the working application.
It's achievable even if the two dll versions have the same public token.
Here the steps to achieve this:
Just add the references is not enough, since only the newer one will be copied (even if you enable local copy for both). This give a project tree like this:
At this point you can compile but you still have problems at run-time. To fix those:
app.config
to add an assemblyBinding
.
assemblyIdentity
is the concerned dll.bindingRedirect
map a version range (oldVersion
) to a fixed version (newVersion
).codeBase
map a fixed version
to a file path (href
).bindingRedirect newVersion
and codeBase version
must match and match the version of the used dll.
Here, it's all about the dll assembly version, not the file version
Here is the program output:
This hack source code is available here.
Edit: As sharpiro commented, there is still a warning when the project is built, this is related to this msbuild bug for witch this answer is a workaround.
This may be possible using the extern alias
feature. When you compile, include an alias to the DLL files, e.g.:
csc.exe ... /reference:AV1=v1.0.0.0/A.dll /reference:AV2=v2.0.0.0/A.dll
(This can be set in Visual Studio as well by changing the aliases
property of the reference.)
In the cs files you could use extern alias
to reference the namespaces:
extern alias AV1;
extern alias AV2;
// using statements
This allows you to reference each version independently:
var v1foo = new AV1::Foo();
var v2foo = new AV2::Foo();
For projects that use only one of the DLLs, you can include a reference to the desired version.
// ProjA cs file
extern alias AV1;
using Foo = AV1::Foo; // alternately, path to namespace
...
var foo = new Foo(); // from version 1 of library
// ProjB cs file
extern alias AV2;
using Foo = AV2::Foo; // alternately, path to namespace
...
var foo = new Foo(); // from version 2 of library
This allows both versions of the DLL to be referenced independently in the same solution. (MSDN Reference.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With