Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

System.Buffers version different between net45 and netstandardx #1830

Open
arthur-conde opened this issue Jan 16, 2020 · 9 comments
Open

System.Buffers version different between net45 and netstandardx #1830

arthur-conde opened this issue Jan 16, 2020 · 9 comments
Labels
Milestone

Comments

@arthur-conde
Copy link

I have an issue in a solution utilizing projects running on both .NET 4.7.2 and .NET Standard that reference the ASP.Net Core SignalR client libraries.

The netstandard projects end up depending on System.Buffers 4.5.0 which have an assembly version of 4.0.3.0. The net472 projects end up pulling in a reference to the dll inside lib/ref which has an assembly version of 4.0.2.0.

We have a tool that scans our assemblies and ensures its dependencies are available. I believe because of this mismatch, our tool is reporting that a dependency is missing, as it's expecting different versions of the same assembly.

Unable to load reference for System.Memory, Version=4.0.1.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51 Could not load file or assembly 'System.Buffers, Version=4.0.2.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040) WRN: Assembly binding logging is turned OFF. To enable assembly bind failure logging, set the registry value [HKLM\Software\Microsoft\Fusion!EnableLog] (DWORD) to 1.

While we are currently ignoring this when it comes up, it's not a solution.

Are there any recommendations on how to resolve this?

@Dotnet-GitSync-Bot Dotnet-GitSync-Bot added area-System.Buffers untriaged New issue has not been triaged by the area owner labels Jan 16, 2020
@mletterle
Copy link
Contributor

I've ran into this too, there really needs to be a new version of System.Buffers with the version numbers all aligned. The best work around I've found so far is to explicitly reference System.Buffers version 4.4.0 on the net472 project.

The root of this, is the fact that even though net472 is newer than net45 they are technically the same "framework" and so the NuGet package resolution prefers the net45 version over the netstandard version (even though net472's "compatibility" is closer to netstandard2.0 than net45).

The 4.4.0 version of the System.Buffers NuGet package doesn't have a full framework reference assembly, only netstandard versions. So it picks the netstandard reference assembly same as the netstandard project.

There are other workarounds if you can't downgrade, but at that point you're bypassing NuGet resolution all together.

Also related to the following NuGet issues:

NuGet/Home#7416
NuGet/Home#7385
NuGet/Home#5370

Related sdk issue: dotnet/sdk#1791

@GrabYourPitchforks GrabYourPitchforks added the packaging Related to packaging label Feb 21, 2020
@GrabYourPitchforks GrabYourPitchforks added this to the 5.0 milestone Feb 21, 2020
@GrabYourPitchforks GrabYourPitchforks removed the untriaged New issue has not been triaged by the area owner label Feb 21, 2020
@GrabYourPitchforks
Copy link
Member

cc @joperezr

@joperezr
Copy link
Member

@arthur-conde I just tried your repro locally and I see what you are saying, so looks like System.Buffers package version 4.5.0 has the following two assets:

ref/netstandard2.0/System.Buffers.dll  // -> this one with Assembly Version 4.0.2.0
lib/netstandard2.0/System.Buffers.dll // -> this one with Assembly Version 4.0.3.0

However, this should be completely fine, as the way that the .NET Core loader works, if an assembly compiled against 4.0.2.0 but got 4.0.3.0 at runtime, the loader will load this assembly just fine because the version is greater. In fact, in servicing this is usually the way we service OOB packages in which we usually just rev' up the implementation assembly's version, but not the reference assembly. Can you elaborate a bit more why is it that this is a problem for you? Does this tool that you run take into consideration the .NET Core loader rules of when its ok to use a different version?

@adamsitnik
Copy link
Member

@ericstj is there anything we could do to align the version numbers?

@adamsitnik adamsitnik modified the milestones: 5.0.0, Future Jul 6, 2020
@joperezr
Copy link
Member

joperezr commented Jul 6, 2020

not sure what you mean about aligning version numbers but we don't build this package any longer so no change to modify this on 5.0, all we could do is in servicing and we don't really have the option to downgrade an implementation assembly version and increasing the assembly version of the ref could cause many other issues, so I'm more interested into understanding why is this a problem today before we decide what the fix should be or whether we should do it.

@adamsitnik
Copy link
Member

not sure what you mean about aligning version numbers but we don't build this package any longer so no change to modify this on 5.0, all we could do is in servicing and we don't really have the option to downgrade an implementation assembly version and increasing the assembly version of the ref could cause many other issues

thanks for the explanation, I forgot that this is the "special" package (I was hoping that we can provide some easy fix)

I'm more interested into understanding why is this a problem today before we decide what the fix should be or whether we should do it

very good point! @arthur-conde could you please respond to the question asked by @joperezr above

@peter-dolkens
Copy link

I'm more interested into understanding why is this a problem today before we decide what the fix should be or whether we should do it.

The issue is this. Quite often when working with .Net Framwork projects, you'll encounter an error that looks something like (version numbers could be slightly different):

Could not load file or assembly 'System.Buffers, Version=4.0.2.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)

Now normally we'd just go, check the version we've got and update the binding redirects in web.config, but a quick check of System.Buffers.dll reveals:
image

That's not a particularly useful version number. Most binaries will match that to the assembly version, but instead we need to load the binary into another program to retrieve that information. This is just extra friction when people are already wrestling with the mess caused by the migration from Framework to .Net Core.

Don't get me wrong, I love Core, but mistakes were made around versioning during the transition, and for those of us maintaining legacy codebases, those mistakes are coming back to bite us every day, and simple things like "make the file version match the assembly version" are very basic QoL improvements that can make the life of those supporting the old framework a little better.

"Move fast and break things" is great and everything, until you're tasked with fixing something that someone else broke.

@lostromb
Copy link

lostromb commented Nov 9, 2022

I want to +1 on this issue as I just hit it as well. I have a .Net 4.8 app which uses some complicated reflection and AppDomain remoting, so assembly versioning can get pretty fragile, and it just hit
FileLoadException: Could not load file or assembly 'System.Buffers, Version=4.0.2.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)

Using DotPeek to look at the contents of System.Buffers.4.5.1.nupkg (the latest available with 270 million downloads), the versions make no sense:

File Assembly Version
\ref\netstandard1.1\System.Buffers.dll 4.0.2.0
\ref\netstandard2.0\System.Buffers.dll 4.0.2.0
\ref\net45\System.Buffers.dll 4.0.3.0
\lib\netstandard1.1\System.Buffers.dll 4.0.3.0
\lib\netstandard2.0\System.Buffers.dll 4.0.3.0
\lib\net461\System.Buffers.dll 4.0.3.0

Why are the reference assemblies set to version 4.0.2.0, except for the reference assembly for net45 which is 4.0.3.0? And then all of the implementations have version 4.0.3.0 so it seems like if you compile against the reference for .Net Standard you would also have to use a binding redirect somewhere along the line. It just seems so arbitrary and error-prone.

@joperezr
Copy link
Member

joperezr commented Nov 9, 2022

Please take a look at this recent issue which was just closed that is very similar. This reply in particular explains why versions inside NuGet packages don't always align. When using NuGet packages and targeting .NET Framework, making sure auto-binding redirects are enabled is almost always a requirement.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

8 participants