(The original issue was reported by Gyuwon Yi from here: https://developercommunity.visualstudio.com/content/problem/102236/unit-test-projectnet-47-cannot-load-systemvaluetup.html )
Unit Test project(.NET 4.7) referencing .NET Core library using value tuple cannot load System.ValueTuple assembly.
But console client application works correctly.
You can repro with code from https://github.com/gyuwon/ValueTypeTestingProblem
The whole message:
Test Name: Bar_returns_value_tuple_correctly
Test FullName: ValueTupleTestsNet47.FooService_specs.Bar_returns_value_tuple_correctly
Test Source: c:\users\gyuwonDocuments\Projects\ValueTupleTesting\ValueTupleTestsNet47\FooService_specs.cs : line 16
Test Outcome: Failed
Test Duration: 0:00:00.0261781 Result StackTrace: at ValueTupleTestsNet47.FooService_specs.Bar_returns_value_tuple_correctly()
Result Message:
Test method ValueTupleTestsNet47.FooService_specs.Bar_returns_value_tuple_correctly threw exception:
System.IO.FileLoadException: Could not load file or assembly 'System.ValueTuple, Version=0.0.0.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)
As I replied on the original issue, it can be solved by making library project to target multiple frameworks.
But it's just a work-around, not a solution.
I think it's not a single ValueTuple problem. There's some referencing issue on .NET Standard 2.0.
For example this issue on Azure Function(Web Job) project with .NET Standard 2.0 library, looks like similar: https://github.com/Azure/azure-webjobs-sdk-script/issues/1792
Does adding these properties to the test project's csproj file help?:
<PropertyGroup>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
</PropertyGroup>
@dasMulli Unfortunately BindingRedirect does not help. :'(
This issue is easily reproduced by creating a .Net Standard 2.0 project with a function that uses a ValueTuple (such as public (int, int) Test() { return (1, 1); }) and calling that function (or calling any number of functions that eventually calls a ValueTuple function) from a .Net Framework application (such as unit test, console application, windows form, asp.net).
The exception occurs when the ValueTuple type is needed - not when a ValueTuple is passed from the .Net Standard to .Net Framework project. Actually, the ValueTuple does not even need to be used in the .Net Framework project.
When running under a .Net Core 2, the type is
System.ValueTuple, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e.
When running under .Net Framework 4.6.1, the type is
System.ValueTuple, System.ValueTuple, Version=4.0.2.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51.
But, when starting with a .Net Framework 4.6.1 applicaiton, the .Net Standard 2.0 code wants:
System.ValueTuple, Version=0.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51
A workaround is to use a binding redirect in app.config:
<dependentAssembly>
<assemblyIdentity name="System.ValueTuple" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0"/>
</dependentAssembly>
However, this does not work in all situations. For example, some Unit Tests setups will execute from a separate folder and will not load the unit test projects app.config. Also, ComVisible projects will not use the app.config.
It seems that a simple version number change would resolve the issue.
I've seen quite a few issues on github due to the problem. This shows that many people are having trouble and spending time on this...
https://github.com/dotnet/standard/issues/446
https://github.com/aspnet/EntityFrameworkCore/issues/9046
https://github.com/julielerman/EFCore2NightlyNet461/issues/1
https://github.com/ErikEJ/EntityFramework.SqlServerCompact/issues/463
https://github.com/dotnet/roslyn/pull/21832
and more...
It seems that a simple version number change would resolve the issue.
Unfortunately that isn't possible because there are different assembly versions on different platforms and they already exist.
I agree this issue can be painful but the general issue stems from the .NET Framework being much more strict with assembly binding which is why you need the binding redirects.
If you guys can give me the scenarios where the binding redirects aren't working I can try and help figure out a solution.
@weshaggard
If you guys can give me the scenarios where the binding redirects aren't working I can try and help figure out a solution.
These 2 situations are fairly easy to reproduce:
ComVisible: In a .Net Framework project, expose a class as [ComVisible(true)] that executes another function in a .Net Standard project that uses ValueTuple. Register the dll with regasm. In VBScript (or Classic ASP), use CreateObject on the .Net Framework object and call the function. App.Config files are not used for COM objects. Using AutoGenerateBindingRedirects creates the redirects in the output config file - which COM will not use.
PowerShell: Using the same .Net Framework object (ComVisible not necessary), Import the dll into powershell, use New-Object and call the function. Powershell does not use the app.config file.
@chrisw13 thanks for the scenarios.
@ericstj @terrajobst do you guys know whether the COM activation honors binding redirects?
For the Powershell or any case where there is an extension model (msbuild is another example) you are at the mercy of the host application to correctly load dependencies. In those cases you essentially are targeting a custom platform that the host application defines and you can only use things they allow. This isn't new but it is true that using .NET Standard 2.0 might make some of these issues more common. So there isn't any one generic solution to these problems depending on the host you might have to solve them differently,.
Perhaps helpful: steps above didn't work for me with VS 2017 15.3.3, but started working with VS 2017 15.3.4.
Can't seem to get this to work when running an azure function against a .net standard library
@BinaryPatrick
That's probably because Azure Functions don't work with .NET Standard 2.0 yet.
Not even precompiled?
This got things working for me. Seeing as there isn't a app.config this fix seems to work.
I don't have an app.config file in my MS unit test projects, how do I apply the workaround?
Unit tests (both mstest and xunit) use the .dll.config convention.
NUnit picks up .dll.config as well.
VS2017 15.4.0 here. not a Core2.0 project & the System.ValueTuple won't update / won't redirect.
I am now having this issue as well. I created an Azure Function (HttpTrigger). It runs locally and even runs while deployed to Azure. However, it fails during CI check-in using VSTS with the same error message as above. I have tried the code workaround, I have tried added System.ValueTuple thru NuGet, all have failed. Is there a solution to have this build in VSTS?
VS 15.5.7, .NET Standard 2.0, Azure Function project. Microsoft.NET.Sdk.Functions
(1.0.8). Won't build. Compile error in Visual Studio.
Error System.IO.FileNotFoundException: Could not load file or assembly 'System.ValueTuple, Version=4.0.2.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51' or one of its dependencies. The system cannot find the file specified.
Deleting the following folder worked for me. Project now compiles.
C:\Users\name.nuget\packages\microsoft.net.sdk.functions1.0.8\build\netstandard1.0
Visual Studio 15.5.7, .NET Standard 2.0, Microsoft.NET.Sdk.Functions (1.0.8)
I'm closing this because it doesn't bother me anymore.
I'm tracking related issues and information in a list. They are related to System.Net.Http, System.Runtime, System.IO, System.ValueTuple, System.Buffers and others.
https://github.com/dotnet/corefx/issues/32587
https://github.com/dotnet/corefx/issues/32561
https://github.com/dotnet/standard/issues/481
https://github.com/dotnet/standard/issues/567
https://github.com/dotnet/standard/issues/558
https://github.com/dotnet/standard/issues/887
https://github.com/dotnet/standard/issues/891
https://github.com/dotnet/corefx/issues/32610
https://github.com/dotnet/corefx/issues/30642
https://github.com/dotnet/corefx/issues/32757
https://github.com/dotnet/standard/issues/895
https://github.com/dotnet/standard/issues/877
https://github.com/dotnet/standard/issues/521
https://github.com/dotnet/standard/issues/295
https://github.com/dotnet/standard/issues/476
https://github.com/dotnet/standard/issues/184
https://github.com/dotnet/standard/issues/936
https://github.com/dotnet/standard/issues/941
https://github.com/dotnet/corefx/issues/33148
https://github.com/NuGet/Home/issues/7440
https://github.com/dotnet/corefx/issues/31532
https://github.com/dotnet/corefx/issues/22781
https://github.com/dotnet/corefx/issues/23306
https://github.com/dotnet/corefx/issues/29622
https://github.com/dotnet/corefx/issues/9846
https://github.com/dotnet/corefx/issues/17522
https://github.com/dotnet/corefx/issues/25773
All of these have the same very few underlying issues.
.NET 4.7.2 helps with some but not all of these. You can look at my comments on some of these issues for some ideas on how to work around those problems. I also have a central list of ideas to try.
I ran into this problem today and solved by applying multiple framework targets for the .net-standard project.
That way the compiler compiles a version for each framework and links the correct one.
<PropertyGroup>
<TargetFrameworks>net472;net5.0;netstandard2.0</TargetFrameworks>
</PropertyGroup>
Note that it's TargetFrameworkS, plural.
Most helpful comment
Does adding these properties to the test project's csproj file help?: