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

(Packaging issue in System.IO.FileSystem) System.IO.File in .NET Standard library fails when run in unit test #20284

Closed
smadala opened this issue Feb 20, 2017 · 28 comments

Comments

@smadala
Copy link

smadala commented Feb 20, 2017

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

@smadala
Copy link
Author

smadala commented Feb 20, 2017

From @davkean on January 20, 2017 3:49

From @srivatsn on December 16, 2016 20:31

@codito

@smadala
Copy link
Author

smadala commented Feb 20, 2017

From @davkean on January 20, 2017 3:49

From @srivatsn on December 20, 2016 22:57

@dotnet/vstest

@smadala
Copy link
Author

smadala commented Feb 20, 2017

From @davkean on January 20, 2017 3:49

From @codito on December 21, 2016 12:50

We're investigating this issue. As a workaround, please use <PackageReference Include="NETStandard.Library" Version="1.6.0" /> instead of 1.6.1 in netstdlib.csproj.

@smadala
Copy link
Author

smadala commented Feb 20, 2017

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 :-) )

@smadala
Copy link
Author

smadala commented Feb 20, 2017

There is mismatch between version number of .nuget\packages\system.io.filesystem\4.3.0\ref\netstandard1.3\System.IO.FileSystem.dll (4.0.1) and .nuget\packages\system.io.filesystem\4.3.0\lib\net46\System.IO.FileSystem.dll(4.0.2).
There is no .nuget\packages\system.io.filesystem\4.3.0\lib\netstandard1.3\System.IO.FileSystem.dll file.

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.

Sln with console app - repro-netstandard-systemio.zip

@smadala
Copy link
Author

smadala commented Feb 20, 2017

From @codito on February 20, 2017 14:55

@smadala packaging issue in corefx?

@smadala
Copy link
Author

smadala commented Feb 20, 2017

Could be, moving to corefx.

@smadala smadala changed the title System.IO.File in .NET Standard library fails when run in unit test (Packageing issue in System.IO.FileSystem) System.IO.File in .NET Standard library fails when run in unit test Feb 20, 2017
@smadala smadala changed the title (Packageing issue in System.IO.FileSystem) System.IO.File in .NET Standard library fails when run in unit test (Packaging issue in System.IO.FileSystem) System.IO.File in .NET Standard library fails when run in unit test Feb 20, 2017
@ianhays
Copy link
Contributor

ianhays commented Mar 10, 2017

cc @ericstj @mellinoe for packaging.

@ericstj
Copy link
Member

ericstj commented Mar 13, 2017

Mismatch is expected. You need to use bindingRedirects with any of these packages.

@daveaglick
Copy link

daveaglick commented Mar 13, 2017

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
e:\Code\Scripty\src\Scripty.MsBuild.Tests>"C:\Program Files (x86)\MSBuild\14.0\bin\amd64\msbuild.exe" "E:\Code\Scripty\src\Scripty.MsBuild.Tests\SampleSolution\Sample.sln" /p:ScriptyAssembly="E:\Code\Scripty\src\Scripty.MsBuild.Tests\bin\Debug\Scripty.MsBuild.dll";Include1=true;Include3=true
Microsoft (R) Build Engine version 14.0.25420.1
Copyright (C) Microsoft Corporation. All rights reserved.

Building the projects in this solution one at a time. To enable parallel build, please add the "/m" switch.
Build started 3/13/2017 4:24:57 PM.
Project "E:\Code\Scripty\src\Scripty.MsBuild.Tests\SampleSolution\Sample.sln" on node 1 (default targets).
ValidateSolutionConfiguration:
  Building solution configuration "Debug|Any CPU".
Project "E:\Code\Scripty\src\Scripty.MsBuild.Tests\SampleSolution\Sample.sln" (1) is building "E:\Code\Scripty\src\Scripty.MsBuild.Tests\SampleSolu tion\Proj\Proj.csproj" (2) on node 1 (default targets).
EvaluateScriptyFiles:
  Starting out-of-process script evaluation...
  Arguments: --solution "E:\Code\Scripty\src\Scripty.MsBuild.Tests\SampleSolution\Sample.sln" --p "ScriptyAssembly=E:\Code\Scripty\src\Scripty.MsBu
  ild.Tests\bin\Debug\Scripty.MsBuild.dll" --p "Include1=true" --p "Include3=true" "E:\Code\Scripty\src\Scripty.MsBuild.Tests\SampleSolution\Proj\P
  roj.csproj" "E:\Code\Scripty\src\Scripty.MsBuild.Tests\SampleSolution\Proj\Test.csx"
  Finished script evaluation
E:\Code\Scripty\src\Scripty.MsBuild\Scripty.MsBuild.targets(27,5): error : System.IO.FileNotFoundException: Could not load file or assembly 'System .IO.FileSystem, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file spec ified. [E:\Code\Scripty\src\Scripty.MsBuild.Tests\SampleSolution\Proj\Proj.csproj]
E:\Code\Scripty\src\Scripty.MsBuild\Scripty.MsBuild.targets(27,5): error : File name: 'System.IO.FileSystem, Version=4.0.2.0, Culture=neutral, Publ icKeyToken=b03f5f7f11d50a3a' ---> System.IO.FileNotFoundException: Could not load file or assembly 'System.IO.FileSystem, Version=4.0.1.0, Culture= neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified. [E:\Code\Scripty\src\Scripty.MsBui ld.Tests\SampleSolution\Proj\Proj.csproj]
E:\Code\Scripty\src\Scripty.MsBuild\Scripty.MsBuild.targets(27,5): error : File name: 'System.IO.FileSystem, Version=4.0.1.0, Culture=neutral, Publ icKeyToken=b03f5f7f11d50a3a' [E:\Code\Scripty\src\Scripty.MsBuild.Tests\SampleSolution\Proj\Proj.csproj]
E:\Code\Scripty\src\Scripty.MsBuild\Scripty.MsBuild.targets(27,5): error : Assembly manager loaded from:  C:\Windows\Microsoft.NET\Framework\v4.0.3 0319\clr.dll [E:\Code\Scripty\src\Scripty.MsBuild.Tests\SampleSolution\Proj\Proj.csproj]
E:\Code\Scripty\src\Scripty.MsBuild\Scripty.MsBuild.targets(27,5): error : Running under executable  E:\Code\Scripty\src\Scripty.MsBuild.Tests\bin\ Debug\Scripty.exe [E:\Code\Scripty\src\Scripty.MsBuild.Tests\SampleSolution\Proj\Proj.csproj]
E:\Code\Scripty\src\Scripty.MsBuild\Scripty.MsBuild.targets(27,5): error : --- A detailed error log follows.  [E:\Code\Scripty\src\Scripty.MsBuild. Tests\SampleSolution\Proj\Proj.csproj]
E:\Code\Scripty\src\Scripty.MsBuild\Scripty.MsBuild.targets(27,5): error : === Pre-bind state information === [E:\Code\Scripty\src\Scripty.MsBuild. Tests\SampleSolution\Proj\Proj.csproj]
E:\Code\Scripty\src\Scripty.MsBuild\Scripty.MsBuild.targets(27,5): error : LOG: DisplayName = System.IO.FileSystem, Version=4.0.1.0, Culture=neutra l, PublicKeyToken=b03f5f7f11d50a3a [E:\Code\Scripty\src\Scripty.MsBuild.Tests\SampleSolution\Proj\Proj.csproj]
E:\Code\Scripty\src\Scripty.MsBuild\Scripty.MsBuild.targets(27,5): error :  (Fully-specified) [E:\Code\Scripty\src\Scripty.MsBuild.Tests\SampleSolu tion\Proj\Proj.csproj]
E:\Code\Scripty\src\Scripty.MsBuild\Scripty.MsBuild.targets(27,5): error : LOG: Appbase = file:///E:/Code/Scripty/src/Scripty.MsBuild.Tests/bin/Deb ug/ [E:\Code\Scripty\src\Scripty.MsBuild.Tests\SampleSolution\Proj\Proj.csproj]
E:\Code\Scripty\src\Scripty.MsBuild\Scripty.MsBuild.targets(27,5): error : LOG: Initial PrivatePath = NULL [E:\Code\Scripty\src\Scripty.MsBuild.Tes ts\SampleSolution\Proj\Proj.csproj]
E:\Code\Scripty\src\Scripty.MsBuild\Scripty.MsBuild.targets(27,5): error : Calling assembly : Microsoft.CodeAnalysis, Version=2.0.0.0, Culture=neut ral, PublicKeyToken=31bf3856ad364e35. [E:\Code\Scripty\src\Scripty.MsBuild.Tests\SampleSolution\Proj\Proj.csproj]
E:\Code\Scripty\src\Scripty.MsBuild\Scripty.MsBuild.targets(27,5): error : === [E:\Code\Scripty\src\Scripty.MsBuild.Tests\SampleSolution\Proj\Proj. csproj]
E:\Code\Scripty\src\Scripty.MsBuild\Scripty.MsBuild.targets(27,5): error : LOG: This bind starts in default load context. [E:\Code\Scripty\src\Scri pty.MsBuild.Tests\SampleSolution\Proj\Proj.csproj]
E:\Code\Scripty\src\Scripty.MsBuild\Scripty.MsBuild.targets(27,5): error : LOG: Using application configuration file: E:\Code\Scripty\src\Scripty.M sBuild.Tests\bin\Debug\Scripty.exe.Config [E:\Code\Scripty\src\Scripty.MsBuild.Tests\SampleSolution\Proj\Proj.csproj]
E:\Code\Scripty\src\Scripty.MsBuild\Scripty.MsBuild.targets(27,5): error : LOG: Using host configuration file:  [E:\Code\Scripty\src\Scripty.MsBuil d.Tests\SampleSolution\Proj\Proj.csproj]
E:\Code\Scripty\src\Scripty.MsBuild\Scripty.MsBuild.targets(27,5): error : LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Fram ework\v4.0.30319\config\machine.config. [E:\Code\Scripty\src\Scripty.MsBuild.Tests\SampleSolution\Proj\Proj.csproj]
E:\Code\Scripty\src\Scripty.MsBuild\Scripty.MsBuild.targets(27,5): error : LOG: Attempting download of new URL file:///E:/Code/Scripty/src/Scripty. MsBuild.Tests/bin/Debug/System.IO.FileSystem.DLL. [E:\Code\Scripty\src\Scripty.MsBuild.Tests\SampleSolution\Proj\Proj.csproj]
E:\Code\Scripty\src\Scripty.MsBuild\Scripty.MsBuild.targets(27,5): error : LOG: Attempting download of new URL file:///E:/Code/Scripty/src/Scripty. MsBuild.Tests/bin/Debug/System.IO.FileSystem/System.IO.FileSystem.DLL. [E:\Code\Scripty\src\Scripty.MsBuild.Tests\SampleSolution\Proj\Proj.csproj]
E:\Code\Scripty\src\Scripty.MsBuild\Scripty.MsBuild.targets(27,5): error : LOG: Attempting download of new URL file:///E:/Code/Scripty/src/Scripty. MsBuild.Tests/bin/Debug/System.IO.FileSystem.EXE. [E:\Code\Scripty\src\Scripty.MsBuild.Tests\SampleSolution\Proj\Proj.csproj]
E:\Code\Scripty\src\Scripty.MsBuild\Scripty.MsBuild.targets(27,5): error : LOG: Attempting download of new URL file:///E:/Code/Scripty/src/Scripty. MsBuild.Tests/bin/Debug/System.IO.FileSystem/System.IO.FileSystem.EXE. [E:\Code\Scripty\src\Scripty.MsBuild.Tests\SampleSolution\Proj\Proj.csproj]
E:\Code\Scripty\src\Scripty.MsBuild\Scripty.MsBuild.targets(27,5): error :    at Roslyn.Utilities.FileUtilities.OpenFileStream(String path) [E:\Cod e\Scripty\src\Scripty.MsBuild.Tests\SampleSolution\Proj\Proj.csproj]
E:\Code\Scripty\src\Scripty.MsBuild\Scripty.MsBuild.targets(27,5): error :    at Microsoft.CodeAnalysis.MetadataReference.CreateFromAssemblyInterna l(Assembly assembly, MetadataReferenceProperties properties, DocumentationProvider documentation) [E:\Code\Scripty\src\Scripty.MsBuild.Tests\Sample Solution\Proj\Proj.csproj]
E:\Code\Scripty\src\Scripty.MsBuild\Scripty.MsBuild.targets(27,5): error :    at Microsoft.CodeAnalysis.Scripting.ScriptOptions.CreateReferenceFrom Assembly(Assembly assembly) [E:\Code\Scripty\src\Scripty.MsBuild.Tests\SampleSolution\Proj\Proj.csproj]
E:\Code\Scripty\src\Scripty.MsBuild\Scripty.MsBuild.targets(27,5): error :    at Microsoft.CodeAnalysis.Scripting.ParameterValidationHelpers.<>c__D isplayClass4_0`2.<SelectChecked>b__0(T item) [E:\Code\Scripty\src\Scripty.MsBuild.Tests\SampleSolution\Proj\Proj.csproj]
E:\Code\Scripty\src\Scripty.MsBuild\Scripty.MsBuild.targets(27,5): error :    at System.Linq.Enumerable.WhereSelectListIterator`2.MoveNext() [E:\Co de\Scripty\src\Scripty.MsBuild.Tests\SampleSolution\Proj\Proj.csproj]
E:\Code\Scripty\src\Scripty.MsBuild\Scripty.MsBuild.targets(27,5): error :    at Microsoft.CodeAnalysis.Scripting.ParameterValidationHelpers.AddRan geChecked[T](ArrayBuilder`1 builder, IEnumerable`1 items, String parameterName) [E:\Code\Scripty\src\Scripty.MsBuild.Tests\SampleSolution\Proj\Proj .csproj]
E:\Code\Scripty\src\Scripty.MsBuild\Scripty.MsBuild.targets(27,5): error :    at Microsoft.CodeAnalysis.Scripting.ParameterValidationHelpers.ToImmu tableArrayChecked[T](IEnumerable`1 items, String parameterName) [E:\Code\Scripty\src\Scripty.MsBuild.Tests\SampleSolution\Proj\Proj.csproj]
E:\Code\Scripty\src\Scripty.MsBuild\Scripty.MsBuild.targets(27,5): error :    at Microsoft.CodeAnalysis.Scripting.ScriptOptions.WithReferences(IEnu merable`1 references) [E:\Code\Scripty\src\Scripty.MsBuild.Tests\SampleSolution\Proj\Proj.csproj]
E:\Code\Scripty\src\Scripty.MsBuild\Scripty.MsBuild.targets(27,5): error :    at Microsoft.CodeAnalysis.Scripting.ScriptOptions.WithReferences(IEnu merable`1 references) [E:\Code\Scripty\src\Scripty.MsBuild.Tests\SampleSolution\Proj\Proj.csproj]
E:\Code\Scripty\src\Scripty.MsBuild\Scripty.MsBuild.targets(27,5): error :    at Scripty.Core.ScriptEngine.<Evaluate>d__6.MoveNext() in E:\Code\Scr ipty\src\Scripty.Core\ScriptEngine.cs:line 74 [E:\Code\Scripty\src\Scripty.MsBuild.Tests\SampleSolution\Proj\Proj.csproj]
  Output file count: 0
GenerateTargetFrameworkMonikerAttribute:
Skipping target "GenerateTargetFrameworkMonikerAttribute" because all output files are up-to-date with respect to the input files.
C:\Program Files (x86)\MSBuild\14.0\bin\amd64\Microsoft.CSharp.CurrentVersion.targets(133,9): warning MSB3884: Could not find rule set file "Manage dMinimumRules.ruleset". [E:\Code\Scripty\src\Scripty.MsBuild.Tests\SampleSolution\Proj\Proj.csproj]
CoreCompile:
Skipping target "CoreCompile" because all output files are up-to-date with respect to the input files.
CopyFilesToOutputDirectory:
  Proj -> E:\Code\Scripty\src\Scripty.MsBuild.Tests\SampleSolution\Proj\bin\Debug\ProjA.dll
Done Building Project "E:\Code\Scripty\src\Scripty.MsBuild.Tests\SampleSolution\Proj\Proj.csproj" (default targets).

Done Building Project "E:\Code\Scripty\src\Scripty.MsBuild.Tests\SampleSolution\Sample.sln" (default targets).


Build succeeded.

@Portikus
Copy link

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.
Adding System.Runtime.Serialization.Primitives nuget package (Version 4.1.1) to the UnitTest project works as a workaround.

@olegtk
Copy link

olegtk commented Apr 2, 2017

Any updates on this? What's a workaround for project.json based projects?

@gulbanana
Copy link

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.

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="System.IO.FileSystem" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" />
      </dependentAssembly>
    </assemblyBinding>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="System.Collections.Immutable" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-1.2.1.0" newVersion="1.2.1.0" />
      </dependentAssembly>
    </assemblyBinding>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="System.Security.Cryptography.Algorithms" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-4.1.0.0" newVersion="4.1.0.0" />
      </dependentAssembly>
    </assemblyBinding>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="System.Security.Cryptography.Primitives" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-4.1.0.0" newVersion="4.0.1.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>

@ericstj
Copy link
Member

ericstj commented Apr 3, 2017

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.

@ericstj ericstj closed this as completed Apr 3, 2017
@olegtk
Copy link

olegtk commented Apr 3, 2017

@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.

@gulbanana
Copy link

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.

@ericstj
Copy link
Member

ericstj commented Apr 3, 2017

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.

@hardcoder
Copy link

hardcoder commented Apr 12, 2017

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:

  • NETStandard 1.4 class library + Nuget package "System.IO.FileSystem"
  • NET Framework 4.6.1 project + NUnit

@olegtk
Copy link

olegtk commented Apr 27, 2017

@AsanX which version? I guess you were just lucky to add specifically the version you needed. Doesn't work for me.

@zahasoftware
Copy link

zahasoftware commented May 29, 2017

I've solve this adding

<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>

in .csproj file.
Ref:
https://msdn.microsoft.com/en-us/library/2fc472t2.aspx

@JoseFMP
Copy link

JoseFMP commented Jun 13, 2017

Any updates other than hack manually the binding redirects ... ?
I mean, any real fix not hacks?

@ericstj
Copy link
Member

ericstj commented Jun 13, 2017

@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.

@dazinator
Copy link

I experienced this with my xunit project not generating binding redirects. You also have make sure you have this:

 <OutputType>Exe</OutputType>

As binding redirects are only generated for executables not libraries.

@kzu
Copy link
Contributor

kzu commented Aug 28, 2017

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:

  • ref\netstandard1.3\System.IO.FileSystem.dll, version 4.0.1.0
  • lib\net46\System.IO.FileSystem.dll, version 4.0.2.0

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.

@bradwilson
Copy link

Binding redirects being generated only for executables should be considered a Pri 1 bug.

@ericstj
Copy link
Member

ericstj commented Aug 28, 2017

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.

@ericstj
Copy link
Member

ericstj commented Aug 28, 2017

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

That's not a mistake, it is very intentional.

In a nutshell, here is how we must version the assemblies in those packages:

  1. Desktop assemblies must always have a matching version for ref and lib so that they get correct binding redirects.
  2. Desktop assemblies must version with every release of the package so that folks don't get downgraded when someone installs an older version of the package in the GAC.
  3. NETStandard reference assemblies which have external implementers (EG: inbox in xamarin, desktop) can never version since that would put them at a higher version than external implementers.

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.

@ericstj
Copy link
Member

ericstj commented Aug 28, 2017

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.

sbomer referenced this issue in sbomer/linker Sep 8, 2017
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.
marek-safar referenced this issue in dotnet/linker Sep 11, 2017
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.
@msftgits msftgits transferred this issue from dotnet/corefx Jan 31, 2020
@msftgits msftgits added this to the 2.0.0 milestone Jan 31, 2020
@dotnet dotnet locked as resolved and limited conversation to collaborators Dec 25, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests