3
votes

Firstly sorry if this has been asked before. I have searched and searched there is a lot conflicting and outdated information as netstandard2.0 has been released.

I am learning the new netstandard and core migrations and have built empty vanilla "hello world" projects using CLI dotnet commands. There are Nuget references.

The issue is adding a reference from a netstandard2.0 classlib to a net461 classlib causes an error (netstandard2.0 --> net461 reference)

"cannot be added due to incompatible targeted frameworks between the two projects. Please review the project you are trying to add and verify that is compatible with the following targets"

This microsoft article by Rich Lander claims that I can do this with netstandard2.0

https://blogs.msdn.microsoft.com/dotnet/2017/06/28/announcing-net-core-2-0-preview-2/#user-content-reference-net-framework-libraries-from-net-standard

Also Immo Landwerth [MSFT] in his article seemed to allude possibility via a compatibility shim, which I believe maybe by Nuget reference only:

https://blogs.msdn.microsoft.com/dotnet/2016/09/26/introducing-net-standard/

enter image description here

(perhaps Scott Hanselman can help!)

It appears that netsandard2.0 supports net461, the ".NET implementation support" grid shows that.

https://docs.microsoft.com/en-us/dotnet/standard/net-standard

Example code

Have created a GitHub repo to demonstrate this

https://github.com/raxuser100/net_standard_references.git https://github.com/raxuser100/net_standard_references/tree/master

Clone master in the above and run this from a command prompt:

dotnet add .\classlib_netstandard2.0_ref_classLib_net461\classlib_netstandard2.0_ref_classLib_net461.csproj reference .\classlib_net461\classlib_net461.csproj

You will then get the error.

The csproj files have the following contents classlib_net461.csproj

<Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
      <TargetFramework>net461</TargetFramework>
   </PropertyGroup>
</Project>

classlib_netstandard2.0.csproj

<Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
      <TargetFramework>netstandard2.0</TargetFramework>
   </PropertyGroup>
</Project>

CLI DotNet command script

I have used the CLI commands below to create a project structure:

dotnet new console --name console_core2.0 --framework netcoreapp2.0
dotnet new classlib --name classlib_netstandard2.0 --framework netstandard2.0
dotnet new classlib --name classlib_net461 --target-framework-override net461

# netstandard2.0 --> net461 link
dotnet new classlib --name classlib_netstandard2.0_ref_classLib_net461 --framework netstandard2.0

<#
add project a reference 
netstandard2.0 --> net461 link

this returns an error

 cannot be added due to 
incompatible targeted frameworks between the two projects. Please review the project you are trying to add and verify that is compatible with the following targets:
At line:1 char:1


Works if we edit classlib_net461.csproj and add multiple targets including netstandard2.0

 <PropertyGroup>
    <TargetFrameworks>net461;netstandard2.0</TargetFrameworks>
  </PropertyGroup>


#>
dotnet add .\classlib_netstandard2.0_ref_classLib_net461\classlib_netstandard2.0_ref_classLib_net461.csproj reference .\classlib_net461\classlib_net461.csproj

Workaround adding multiple targets to classLib_net461

Works if we edit classlib_net461.csproj and add multiple targets including netstandard2.0

classlib_net461.csproj

<PropertyGroup>
    <TargetFrameworks>net461;netstandard2.0</TargetFrameworks>
</PropertyGroup>

Now when we reference, it works fine as you can see below:

classlib_netstandard2.0_ref_classLib_net461.csproj

<Project Sdk="Microsoft.NET.Sdk">
  <ItemGroup>
    <ProjectReference Include="..\classlib_net461\classlib_net461.csproj" />
  </ItemGroup>

  <PropertyGroup>
    <TargetFramework>netstandard2.0</TargetFramework>
  </PropertyGroup>
</Project>

Does this work because now both classlibs target netstandard2.0

Questions

  • Is there a simple diagram to demystify all of this in simple terms with all the gotcha's!

  • Why does this not work. If an empty netstandard2.0 implements most of net461 then surely it has everything it needs to support a bare net461 reference. I know there are some api's that do not work, namely WPF, however these are bare projects, with no Nuget or direct binary references.

  • Workaround, why does this work? Do we always need to target both net461 and netstandard2.0 in classlib so that they can be referenced by netstandard2.0 only classlib.

  • What is the correct structure for using older .net framwork classlibs (net4.3 onwards) from within a netstandard2.0 classlib.

  • How did this ever work?

    https://blogs.msdn.microsoft.com/dotnet/2017/06/28/announcing-net-core-2-0-preview-2/#user-content-reference-net-framework-libraries-from-net-standard

    enter image description here

1
.netstandard provides a small subset of the classes that are available in net461. The kind that can work on different operating systems and project types. Implicit is that you can't add a reference to a net461 assembly. Because then the build result would not be netstandard anymore. - Hans Passant
There's a PR out already fixing this - slated for MSBuild 15.8, check the GH issue liked in the answer. - Martin Ullrich
The other way around, they ensured that a .netstandard assembly can run on a machine that has net461. And other ones. - Hans Passant
It is supported (core/netstandard => netframework), but it's on the razor's edge of supported, and will fail on incompatible operating systems with a PlatformNotSupportedException. And it'll drive you nuts with all kinds of warnings and binding redirects and FileNotFoundExceptions and fml and System.Net.Http killed my mother. 4.7.2 is a bit better if you use the new csproj format, not at all if you upgrade an older project file. - user1228

1 Answers

0
votes

The support for .NET Standard 2.0+ and .NET Core 2.0+ projects to reference .NET Framework libraries is currently limited to NuGet packages (via a special fallback definition), which is why it does not work for your project-to-project reference.

This may change in an upcoming version of the tooling when MSBuild uses the same resolution strategy for this. See this tracking GitHub issue.