Resolving .NET assembly reference to a different name?
My project references Library1.dll and Library2.dll. Library2.dll has a dependency on Library1.dll, but it was compiled to reference it by a different name, Library1.Net40.dll.
Is there an nice way tell my application to redirect all references for Library1.Net40.dll to resolve to Library1.dll? Maybe something similar开发者_开发百科 to the way you can redirect versions using a <bindingRedirect>?
I've got a solution that handles the AppDomain.AssemblyResolve event, but it's a bit of a hack and am hoping there's a better way to do this.
Edit: For anyone's reference, here's how I ended up solving it using the AppDomain.AssemblyResolve event to redirect to a different assembly.
Have you tried playing with the <codeBase> element?
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Library1.Net40"
publicKeyToken="..."
culture="neutral" />
<codeBase version="2.0.0.0"
href="Library1.dll"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
(Untested; no idea if it works.)
CF: Am putting this update here, because it's a bit long for the comments :)
Good idea, thanks. I got the redirect working but it complains because the names are different, here's the log:
LOG: Attempting download of new URL file:///C:/Project/bin/Library1.dll. LOG: Assembly download was successful. Attempting setup of file: C:\Project\bin\Library1.dll LOG: Entering download cache setup phase. LOG: Assembly Name is: Library1, Version=3.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed WRN: Comparing the assembly name resulted in the mismatch: NAME ERR: The assembly reference did not match the assembly definition found. ERR: Setup failed with hr = 0x80131040. ERR: Failed to complete setup of assembly (hr = 0x80131040). Probing terminated.
When a PARTIAL resolve is applied, the ASSEMBLY NAME must match the filename. However the LOCATION of the file can be different.
Otherwise the Fusion Binding Log will report "WRN: Comparing the assembly name resulted in the mismatch: NAME" and be unable to bind.
(Good news: it is possible to rename the assembly DLL to match the Assembly Name.)
For example:
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-10.0.0.0" newVersion="6.0.0.0" />
<bindingRedirect oldVersion="11.0.0.0-12.0.0.0" newVersion="12.0.0.0" />
<codeBase version="12.0.0.0" href="bin/Newtonsoft.Json.12/Newtonsoft.Json.dll" />
</dependentAssembly>
This resolves bin/Newtonsoft.Json.dll
and bin/Newtonsoft.Json.12/Newtonsoft.Json.dll
, depending on version (6-10 or 11-12, respectively). The NAME successfully matches the filename even though the directory path is different.
N.B. "bin" is itself part of the href to the alternate version; adjust as relevant depending on the application base, which is different than the probe path. In the case about, which is running under IIS, the app base is a level above the bin directoy. (See "LOG: Appbase = .." in the Fusion Log.)
Unfortunately the MSBuild process does not honor the directory structure of Referenced Assemblies automatically, regardless of any configuration files. Set the project to not "Copy Local" the alternative assembly versions and then copy them as part of a secondary process ensuring the correct structure is maintained. If any compiled assembly take the alternate version as a directly reference it might be good to ensure that none are "Copy Local" by default.
精彩评论