dotnet / sdk

Core functionality needed to create .NET Core projects, that is shared between Visual Studio and CLI
https://dot.net/core
MIT License
2.7k stars 1.06k forks source link

.NET 4.6.1 project cannot reference a .NET Standard 1.4 project - conflicting types #514

Closed gulbanana closed 7 years ago

gulbanana commented 7 years ago

Repro: https://github.com/gulbanana/repro-netstandard-httpclient These two projects were created with VS2017 RC Refresh. Neither contains any meaningful code. netstdlib builds ok, but netfxlib fails:

banana@forsyth MINGW64 /c/code/repro-netstandard-httpclient/netfxlib (master)
$ dotnet build
Microsoft (R) Build Engine version 15.1.458.808
Copyright (C) Microsoft Corporation. All rights reserved.

  netstdlib -> C:\code\repro-netstandard-httpclient\netstdlib\bin\Debug\netstandard1.4\netstdlib.dll
C:\Program Files\dotnet\sdk\1.0.0-preview4-004233\Microsoft.Common.CurrentVersion.targets(1909,5): warning MSB3243: No way to resolve conflict between "System.IO.Compression, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" and "System.IO.Compression, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089". Choosing "System.IO.Compression, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" arbitrarily. [C:\code\repro-netstandard-httpclient\netfxlib\netfxlib.csproj]
C:\Program Files\dotnet\sdk\1.0.0-preview4-004233\Microsoft.Common.CurrentVersion.targets(1909,5): warning MSB3243: No way to resolve conflict between "System.Net.Http, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" and "System.Net.Http, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a". Choosing "System.Net.Http, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" arbitrarily. [C:\code\repro-netstandard-httpclient\netfxlib\netfxlib.csproj]
  Consider app.config remapping of assembly "System.IO.Compression, Culture=neutral, PublicKeyToken=b77a5c561934e089" from Version "4.0.0.0" [C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.IO.Compression.dll] to Version "4.1.0.0" [C:\Users\banana\.nuget\packages\system.io.compression\4.1.0\ref\net46\System.IO.Compression.dll] to solve conflict and get rid of warning.
  Consider app.config remapping of assembly "System.Net.Http, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" from Version "4.0.0.0" [C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.Net.Http.dll] to Version "4.1.0.0" [C:\Users\banana\.nuget\packages\system.net.http\4.1.0\ref\net46\System.Net.Http.dll] to solve conflict and get rid of warning.
Class1.cs(9,29): error CS0433: The type 'HttpClient' exists in both 'System.Net.Http, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' and 'System.Net.Http, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' [C:\code\repro-netstandard-httpclient\netfxlib\netfxlib.csproj]

Warnings are present even if you don't add a line of code to either project, and if you try to use any types from System.IO.Compression or System.Net.Http it's an unfixable compile error.

qmfrederik commented 7 years ago

I'm seeing this issue as well. I tried to do what the build warning instructs me to do - I added an assembly binding redirect for S.IO.Compression & S.N.Http, and added an <Include> for the app.config file in my .csproj file, but still get the warnings (see my config below).

Is there any way we can workaround this by updating the project file? It would as I'm currently blocked by this.

Extract from my csproj file:

<Project Sdk="Microsoft.NET.Sdk" ToolsVersion="15.0">
  <ItemGroup>
...
    <None Include="app.config"/>
  </ItemGroup>
</Project>
...

My app.config file:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-9.0.0.0" newVersion="9.0.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.IO.Compression"
                          publicKeyToken="b77a5c561934e089"
                          culture="neutral" />
        <bindingRedirect oldVersion="4.0.0.0-4.1.2.0"
                         newVersion="4.1.2.0"/>
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Net.Http"
                          publicKeyToken="b77a5c561934e089"
                          culture="neutral" />
        <bindingRedirect oldVersion="4.0.0.0-4.1.1.0"
                         newVersion="4.1.1.0"/>
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>

Thanks!

qmfrederik commented 7 years ago

Perhaps worth adding that Entity Framework Core references NETStandard.Library even on net461 so anyone using Entity Framework Core is affected by this: aspnet/EntityFramework#7078

gulbanana commented 7 years ago

referencing netstandard.lib on desktop needs to be made ok to do, as it will become harder and harder to avoid. unfortunately the status quo is that you must avoid it due to issues such as the webrequest inheritance security thing. i think the exacerbating factors with new csproj are twofold: 1) default assembly refs cause immediate clashes 2) binding redirects are no longer a workaround option

but the fundamental underlying cause is the same. a desktop-safe release of netstandard.library is needed asap - we cannot wait for the 2.0 timeframe!

dsplaisted commented 7 years ago

I haven't yet looked into what's going on here, but this is definitely supposed to work and it's important for it to work.

@gulbanana I haven't heard about the webrequest inheritance security thing, if there isn't already an issue open for that please also open one (probably the dotnet/standard repo would be the right place).

gulbanana commented 7 years ago

There is already an issue with plenty of work being done :) It's at https://github.com/dotnet/corefx/issues/11100

The only reason I mentioned it here is that it's another reason we can't yet safely reference netstandard.library from desktop, and therefore a reason that overriding the default reference set doesn't fully work around this issue.

qmfrederik commented 7 years ago

@gulbanana Just wanted to make sure I understand correctly: what you are saying is that there is another issue which also blocks projects which reference NETStandard.Library working reliably on .NET FX, not that this issue is a duplicate of dotnet/corefx#11100, correct?

By looking at dotnet/corefx#11100, it seems that

  1. dotnet/corefx#11100 is a runtime issue, whereas this is a compile time issue
  2. There is a workaround for dotnet/corefx#11100 via manually setting the assembly redirects; whereas this issue is about the dotnet build (msbuild/SDK/CLI) somehow not picking up the assembly binding redirects and the compilation to fail.

My understanding is that the workaround for dotnet/corefx#11100 does not apply here and there is no known workaround for this one, effectively preventing compilation of csproj projects which reference NETStandard.Library for the net461 runtime.

Any workaround for this (or pointers to what we can do to provide a fix - happy to create a PR if needed) would be greatly appreciated :)

dsplaisted commented 7 years ago

I think this is the same issue as https://github.com/Microsoft/msbuild/issues/1329

gulbanana commented 7 years ago

I think that's a component of the problem, but bear in mind the warning is not spurious - it is correctly indicating that you will not be able to use those types.

ericstj commented 7 years ago

This looks to me like the SDK is missing this code that existed in the previous NuGet targets: https://github.com/NuGet/NuGet.BuildTasks/blob/cb9b1a1559efac311b84aacc5f605004ad9e8562/src/Microsoft.NuGet.Build.Tasks/Microsoft.NuGet.targets#L216-L218 That is what made this work in NuGet 3.

RAR is getting a simple name reference which resolves to the targeting pack and the NuGet reference then not resolving the conflicts between the two since they are both primary. We do need RAR to fix that moving forward, so you can let Microsoft/msbuild#1329 track that fix.

jdluzen commented 7 years ago

Also getting this with a brand new project. Library targeting .NETStandard1.6 Tests for the library targeting .NET4.6.1 Windows 10, VS2015.3, .NET Core 1.1.0 SDK 1.0.0 Preview 2.1, .NET Core 1.0.1 VS 2015 tooling Preview 2

Edit: I can continue for now by going down to 1.4.

natidea commented 7 years ago

Similar issue seen in https://github.com/Intellitect/coalesce /cc @MarkMichaelis @GrantErickson

gulbanana commented 7 years ago

looks like the fix will be that the implicitly added ref will be dropped by the sdk when a packageref adds the same library, so we'll end up with just the netstandard version of these dlls in my original scenario. is that a reasonable understanding of #662?

natidea commented 7 years ago

Yes, the fixes in #662 and #671 will prefer any DLLs supplied through the NuGet assets file over implicit framework references. So for the following, the first entry will be chosen:

  Assemblies=
      C:\Users\dev\.nuget\packages\system.net.http\4.1.0\ref\net46\System.Net.Http.dll
              NuGetIsFrameworkReference=false
              NuGetSourceType=Package
              Private=false
      System.Net.Http
              NuGetIsFrameworkReference=true
              NuGetSourceType=Package
              Private=false
gulbanana commented 7 years ago

sounds good, thanks

oliverjanik commented 7 years ago

When will this fix land?