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
(Packaging issue in System.IO.FileSystem) System.IO.File in .NET Standard library fails when run in unit test #20284
Comments
From @davkean on January 20, 2017 3:49 From @gulbanana on December 21, 2016 13:47 I've verified that the workaround works on my system (until I want to use a nuget package which references 1.6.1 :-) ) |
There is mismatch between version number of Due this mismatch System.IO.FileSystem 4.0.1 getting bind in compile time. which is not found in runtime. This issue can be repro with simple console app referring netstdlib. |
Could be, moving to corefx. |
Mismatch is expected. You need to use bindingRedirects with any of these packages. |
FWIW, I'm seeing something similar to this when using Roslyn 2.0.0 from within an MSBuild task (the fact that's it's an MSBuild task is probably not germaine, other than that it makes diagnosing the binding problems harder). I've tried every combination of binding redirects I can think of without luck. I've also tried installing System.IO.FileSystem 4.3.0 directly into the MSBuild task project without any change. Note that while the example below was created for use in a test, I'm not running it through the unit testing framework here - this is directly calling MSBuild on the test solution from the console to eliminate the unit test framework as a source of problems. Update: I've been able to work past my particular problem by doing an xcopy of all netstandard libraries required by Roslyn into the MSBuild task project output folder. That suggests this problem may have been related to the binder not being able to find them from the test assembly location. At this point probably not totally related to this issue (other than these assemblies have conflicts in the first place). Output
|
I had a similar issue with "System.Runtime.Serialization.Primitives". I have the same structure, a .netstandard 1.4 library and a net461 UnitTest project. |
Any updates on this? What's a workaround for project.json based projects? |
Here's an example of the binding redirects I had to write recently to use Roslyn 2.0.0 in an old-msbuild test project.
|
As @gulbanana suggests you can workaround this by manually specifying the bindingRedirects in the old tooling. For MSBuild based tooling please see dotnet/msbuild#1310 that is tracking missing bindingRedirects for dlls. Closing this issue since the problem is in the tooling. |
@gulbanana, @ericstj That doesn't help, now 4.0.2.0 is not found. How do I know which version should I redirect to? My lib is just targeting .netstandard 1.3. |
I found out what versions to use by examining the contents of the bin/Debug folder and opening the DLLs with ilspy to discover their AssemblyVersion. I don't think this issue should be closed - it's a terrible UX and it will never be realistic to expect all .net hosts and tools to work around it. |
That sounds like more reason to push MSBuild to fix automatic bindingRedirects. AssemblyVersion mismatches are a reality of the package-based ecosystem. The .NET Core loader handles them, but desktop still requires bindingRedirects. We need a central fix for this. Please ref-count the MSBuild issue or open a new one if you don't think its covered by existing issues. |
No need to binding redirects. It sounds funny, but adding Nuget package "System.IO.FileSystem" to the test project resolved the issue. Originaly have the same tools set and issue:
|
@AsanX which version? I guess you were just lucky to add specifically the version you needed. Doesn't work for me. |
I've solve this adding <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects> in .csproj file. |
Any updates other than hack manually the binding redirects ... ? |
@jose-cf if you're still seeing issues with the automatic generated bindingRedirects in MSBuild it'd be good to file that issue in the MSBuild repository. If you're not sure please open a new issue with more detail and we can help investigate. |
I experienced this with my xunit project not generating binding redirects. You also have make sure you have this:
As binding redirects are only generated for executables not libraries. |
I think the underlying cause for this is that the nuget package for System.IO.FileSystem (i.e. 4.3.0 at the moment) contains:
This looks like a serious packaging mistake to me. netstandard libraries compiled against this package will bind to 4.0.1.0 and as a consequence, everyone else consuming the library MUST do the binding redirect just to get a core scenario working, since they will get whichever platform lib they need, which will always be the wrong version. It should be considered a build error to generate a package that contains different version numbers between the ref and lib assemblies, since this pretty much guarantees you will get binding errors at runtime. Also, consider that not all "hosts"/apps can control what binding redirects are applied (i.e. a VS extension can hardly make a decision on provinding a binding redirect for such a core assembly without risking breaking everyone else). Maybe there is an actual design decision that went into making the versioning inconsistent within the same package. If so, I'd love to know it so I can understand how this applies (or not) to other nuget authoring scenarios. |
Binding redirects being generated only for executables should be considered a Pri 1 bug. |
Folks, please direct feedback to the https://github.com/Microsoft/MSBuild repo on this. dotnet/msbuild#1310 in particular covers making that work for class libraries. IMO it should also be the default for every project. |
That's not a mistake, it is very intentional. In a nutshell, here is how we must version the assemblies in those packages:
That results in bindingRedirects on desktop, but really just the first two criteria are sufficient (which ANY package that ships a desktop implementation must follow). The fact that we cannot version the netstandard refs makes it more common. |
Furthermore. We realize how painful this can be, which is why in netstandard 2 we reduced the number of assemblies to 1, and it only represents what's inbox in the framework. That way we no longer need to distribute new assemblies of the pieces that make up netstandard surface area in packages. We will still run into some of the versioning constraints like this once we start to graduate things from packages to the framework (System.ValueTuple, System.Memory) but moving forward those problems only exist along the transition as opposed to forever in the future. |
The linker depends on cecil, shipping with a netstandard1.3 build of Mono.Cecil. Some of the reference assemblies for netstandard1.3 have lower versions than the implementation shims that forward types to mscorlib on desktop. To run the linker on desktop, we need to ensure that this version mismatch doesn't cause binding problems. This is the same issue described in https://github.com/dotnet/corefx/issues/16322. Because illink ships as an msbuild task, we can't use binding redirects (msbuild doesn't respect them) to fix this. One option is to implement a custom AssemblyResolve event hook, but this is not robust because it may cause problems when used in combination with other msbuild tasks. Instead, we avoid the version mismatch by using a build of cecil that targets net46 directly, so that we don't need to ship with shims for System.IO.FileSystem.dl and other assemblies.
The linker depends on cecil, shipping with a netstandard1.3 build of Mono.Cecil. Some of the reference assemblies for netstandard1.3 have lower versions than the implementation shims that forward types to mscorlib on desktop. To run the linker on desktop, we need to ensure that this version mismatch doesn't cause binding problems. This is the same issue described in https://github.com/dotnet/corefx/issues/16322. Because illink ships as an msbuild task, we can't use binding redirects (msbuild doesn't respect them) to fix this. One option is to implement a custom AssemblyResolve event hook, but this is not robust because it may cause problems when used in combination with other msbuild tasks. Instead, we avoid the version mismatch by using a build of cecil that targets net46 directly, so that we don't need to ship with shims for System.IO.FileSystem.dl and other assemblies.
From @davkean on January 20, 2017 3:49
From @gulbanana on December 16, 2016 11:28
Possibly this issue should be in a vstest repository but I can't find one.
Repro: https://github.com/gulbanana/repro-netstandard-systemio
When using System.IO in a .NET Standard 1.4 class library, unit tests referencing the library fail. The error is
Message: System.IO.FileLoadException : Could not load file or assembly 'System.IO.FileSystem, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
Copied from original issue: dotnet/project-system#975
Copied from original issue: microsoft/vstest#363
The text was updated successfully, but these errors were encountered: