How does .NET 6 deal with assembly reference conflicts?
Asked Answered
A

1

6

Let's say I got projects A, B and C. Project A references projects B (v. 2.0.0.0) and C (v. 3.0.0.0). Project B references only project C (v. 1.0.0.0). We got a conflict on our hands, since project A and B depend on different assembly versions of project C. In .NET framework we solve this issue using binding redirects. In Project A's app.config file (being the main project) we add:

<dependentAssembly>
    <assemblyIdentity name="C"  
                      publicKeyToken="<somePublicKeyToken>"  
                      culture="en-us" />  

    <bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />  
</dependentAssembly>

I believe that binding redirects are no longer a thing in .NET Core and .NET 5 forward. Instead of referencing an assembly, we reference a NuGet package or a project. My question is: how is this issue solved in newer version of .NET? Why were binding redirects a thing in the first place? Hope my question makes sense.

Alyciaalyda answered 23/3, 2022 at 10:39 Comment(2)
"Instead of referencing an assembly, we reference a NuGet package or a project. " - nah, the csc compiler still generates your .exe/.dll files with good ol' fashioned assembly-references inside of it. And you can still do manual assembly references from .NET Core / .NET 5+ .csproj projects too - it's just kinda buried.Unbraid
Interesting, didn't know that, thanks for pointing out. I tried to find something on the matter but I probably just haven't been googling it properly.Alyciaalyda
H
4

As others pointed out, a package version is a completely different thing from an assembly version. In the end, your build still refers to an assembly. It just happens that the assembly was delivered to your build environment in a package.

You are correct that .Net 5+ does not (by default) require that the assembly version used at runtime match the assembly version used at build time.

I'll speculate that the early design of .Net was attempting to address the "DLL Hell" problem. By formalizing the notion of the DLL version (by placing the version in the metadata of the assembly), an application could verify that it was getting exactly the version that it expected to get, and so would have dependable behavior. Still, you wanted to be able to use a newer version at times, without rebuilding the referring application, so <bindingRedirect was provided.

.Net Core recognizes that it wasn't a successful design. The new approach a) ignores strong naming: it doesn't affect behavior. b) defaults to allowing any version at runtime, and c) provides a new mechanism for enforcing version policy: AssemblyLoadContext

Holism answered 21/5, 2022 at 4:7 Comment(3)
"You are correct that .Net 5+ does not (by default) require that the assembly version used at runtime match the assembly version used at build time." Can you name a source for that? I have just read stackoverflow.com/a/802038 and found that this answer obviously applies to .NET Framework, but not to .NET 5+, see my comment below it. Is this correct?Seaborg
It's hard to find definitive docs (hard to prove a negative?) but learn.microsoft.com/en-us/dotnet/standard/library-guidance/… says "In .NET Core, assembly loading is more relaxed. The .NET Core runtime automatically loads assemblies with a higher version at run time." The new behavior can also be assumed from the docs on assembly loading in .net (core) such as the one I referenced before, and links within it. They say nothing about version matching, while articles on .net framework have a lot to say about it, and <bindingRedirect>.Holism
Versioning rules A single AssemblyLoadContext instance is limited to loading exactly one version of an Assembly per simple assembly name. When an assembly reference is resolved against an AssemblyLoadContext instance that already has an assembly of that name loaded, the requested version is compared to the loaded version. The resolution will succeed only if the loaded version is equal or higher to the requested version.(learn.microsoft.com/en-us/dotnet/core/dependency-loading/…). Notice above quoted last sentence.Insider

© 2022 - 2024 — McMap. All rights reserved.