I'm working on a .NET project for a web application, that has the following setup to reference System.Net.Http
targets .NET Framework 4.8
references assembly version 4.1.1.3
references a nuget package dll local to the project:
..\packages\System.Net.Http.4.3.4\lib\net46\System.Net.Http.dll
The assembly version of the .dll for the package is 4.1.1.3
specifies a runtime redirect:
<bindingRedirect oldVersion="0.0.0.0-4.2.0.0" newVersion="4.0.0.0"/>
When I build the project, it builds successfully. System.Net.Http
is not in the project bin folder, and the GAC has the following version of System.Net.Http
:
v4.0_4.0.0.0
There are no obvious runtime errors when running the web application. Ignoring the fact that this setup looks messy and incorrect, I'd like to understand how .NET is resolving the compilation.
My understanding of what happens in .NET during compilation and runtime is this:
At compile time:
At runtime:
What I'm specifically unclear on is:
System.Net.Http
4.1.1.3 to successfully compile which could then fail at runtime because only v 4.0.0.0 of System.Net.Http
will ever be loaded at runtime?When you build, the compiler uses so called reference assemblies (which contain no executable code, just stubs). The nuget package specifies which assemblies should be referenced from the SDK's reference assemblies and not from the package itself (and therefore not copied to \bin), and that is what you see in the References node in VS. E.g. System.Net.Http reference assembly is located at path "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.8\System.Net.Http.dll". During run time these assemblies are loaded from GAC after applying binding redirects.
On other target frameworks like .net core, a package can either rely on some assemblies being part of the shared framework, or otherwise provide these assemblies as part of build output.
And the answer to your second question is: yes, theoretically version-specific code could fail due to a binding redirect. But I believe automatic binding redirects are generated when you reference multiple assembly version from different projects and libraries, comprising you application, so you have to settle on some particular version to build with.