runtime: System.Numerics.Vectors.dll fails to load
This relates to use of the System.Numerics.Vectors (nuget package 4.5) in a dotnet standard 2.0 library, and consuming that library from a Windows .NET Framework application.
When the runtime attempts to load System.Numerics.Vectors this error is reported…
System.IO.FileNotFoundException
HResult=0x80070002
Message=Could not load file or assembly 'System.Numerics.Vectors, Version=4.1.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified.
Reverting to System.Numerics.Vectors 4.4.0 resolves the problem.
Example code:
dotnet standard 2.0 library class…
namespace FooLib
{
public class Class1
{
public void DoStuff(int[] arr)
{
var va = new Vector<int>(arr, 0);
var vb = new Vector<int>(arr, 4);
var vc = va + vb;
vc.CopyTo(arr, 0);
}
}
}
.NET Franework 4.7 console app
class Program
{
static void Main(string[] args)
{
int[] arr = new int[32];
Class1 c1 = new Class1();
c1.DoStuff(arr);
Console.WriteLine(arr[0]);
}
}
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Reactions: 2
- Comments: 22 (21 by maintainers)
Links to this issue
Commits related to this issue
- Pin System.Numerics.Vectors to 4.4.0 https://github.com/dotnet/corefx/issues/30106 — committed to cdmihai/msbuild by cdmihai 6 years ago
- Pin System.Numerics.Vectors to 4.4.0 https://github.com/dotnet/corefx/issues/30106 — committed to cdmihai/msbuild by cdmihai 6 years ago
- Pin System.Numerics.Vectors to 4.4.0 https://github.com/dotnet/corefx/issues/30106 — committed to cdmihai/msbuild by cdmihai 6 years ago
- Pin System.Numerics.Vectors to 4.4.0 https://github.com/dotnet/corefx/issues/30106 — committed to cdmihai/msbuild by cdmihai 6 years ago
- Pin System.Numerics.Vectors to 4.4.0 https://github.com/dotnet/corefx/issues/30106 — committed to cdmihai/msbuild by cdmihai 6 years ago
- Pin System.Numerics.Vectors to 4.4.0 https://github.com/dotnet/corefx/issues/30106 — committed to cdmihai/msbuild by cdmihai 6 years ago
This sounds much more similar to the problem I had that led me to this issue. In my case, a user has a net47 web site (i.e. no csproj) that references my netstandard2.0 library in a Nuget package. That library package references System.Numerics.Vectors 4.4.0. Since the web site is using packages.config, Nuget Package Manager pulls in System.Numerics.Vectors directly as a dependency when my library is referenced. The site owner then sees the update to System.Numerics.Vectors 4.5.0 offered when she views her available Nuget updates and pulls it in even though her only reference to it is through my library. Boom, my library breaks and the only fix is to either roll back the package update or create a bindingRedirect manually. Is there an equivalent to
AutoGenerateBindingRedirects
that can be used in cases like that?I suspect because the reference assembly and lib assembly versions are different within the Nuget package, the same scenario would play out even if I update my library to reference 4.5.0 directly, because I’m still building against a 4.1.3.0 reference and the bin version will still be 4.1.4.0.
@colgreen the following app.config fixes your unit test project up, same as with the web site I mentioned
@eerhardt Here you go:
VectorProto-v1.zip
It took a while to distill the problem down to a demo solution with only the relevant aspects. In summary, the attached solution contains a .NET Framework 4.7 Unit Test project that refers to a dotnet standard 2.0 library project.
Both the unit test project and the lib project refer to the System.Numerics.Vectors nuget directly, in the original solution this was because there was a unit test that indicates if the hardware acceleration is enabled or not:
As well as other tests against the code in the lib that uses System.Numerics.Vectors if IsHardwareAccelerated == true.
Hence, when I saw the new SNV nuget I updated both projects, ran my unit tests and they started failing! I reverted back to nuget 4.4.0 and they all passed.
Looking deeper (for tracking purposes) this was https://github.com/dotnet/corefx/issues/32457
Thanks for the explanation @eerhardt. I wasn’t aware of the
GenerateBindingRedirectsOutputType
setting, but I guess that doesn’t help with a web site anyway since there’s no project file to put that in. And it’s certainly not intuitive even if that solution is an option. I get that it’s by design and is mitigated in certain toolsets, but man is that a mess…As a library author, it sucks for me, because a certain (not insignificant, I think) segment of my users will download my package and immediately find it doesn’t work. That reflects poorly on me, even if the fix is to create a
bindingRedirect
on their side.As a general user of those packages, it sucks for me because it’s extremely counter-intuitive that I should require a bindingRedirect (whether automagical or manual) to use the library version contained in a package version that I have explicitly and directly referenced. And it’s not exactly easy to track down the correct version to create the bindingRedirect to if you have to add it manually.
If I’m understanding @ericstj ’s explanation correctly, the implementation assembly version number is bumped even though the reference assembly version is frozen just so that desktop users who have GAC’ed the assemblies pick up the new version. If that’s the case, you’ve put the needs of two groups of users at odds with one another. I’d argue (and I’m certainly biased) that people using Nuget distribution as intended should have a clean and intuitive experience and the people who do odd things like GAC-ing a Nuget-distributed assembly should get the pain they’ve brought on themselves. It certainly would work better from my perspective if the implementation assembly version number stayed put once the reference assembly version is frozen.
Thanks @colgreen and @saucecontrol. I am able to repro the problem, and agree with @saucecontrol that the reason this is failing is that the
netstandard2.0
ref assembly (and all previous versions of the package) have an AssemblyVersion less than4.1.4
, and in the latest NuGet package (4.5.0
) has an implementation assembly with AssemblyVersion4.1.4
. When assemblies are referencing different versions of another assembly on .NET Framework projects, you have to use an assembly binding redirect in order for the runtime to load it correctly. (Note on .NET Core this redirect happens automatically using the .deps.json file and TPA list).I wasn’t part of the original AutoGenerateBindingRedirects implementation, so I might not have all the correct info. Hopefully someone corrects me if I’m wrong. But it appears to only kick in when both
AutoGenerateBindingRedirects
andGenerateBindingRedirectsOutputType
are set to true.GenerateBindingRedirectsOutputType
gets defaulted to true when you are an exe or winexe OutputType project. But when you are a unit test or web project (like you both describe), the OutputType isn’t set to exe. So to get the binding redirects to kick in, I needed to set both properties in the unit test project:Assuming your library is targeting
netstandard2.0
, then you are correct.This issue is still “closed”, but I agree it isn’t a dupe of https://github.com/dotnet/sdk/issues/901. Instead, it is by design as @ericstj mentions above - the netstandard2.0 ref assembly was pinned to
4.1.3
because it was made inbox in .NET Core 2.0. Using assembly binding redirects is the correct fix here.This repros on my machine on all tfms from net461 to net472 only when the System.Numerics.Vectors package is added inside a netstandard2.0 library. Referencing it directly from netfx works as expected.