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

.NET Framework 4.7.1 provides built-in support for .NET Standard 2.0 #514

Open
terrajobst opened this Issue Sep 27, 2017 · 55 comments

Comments

Projects
None yet
@terrajobst
Copy link
Member

terrajobst commented Sep 27, 2017

Summary

.NET Framework 4.7.1 will have built-in support for .NET Standard 2.0. This means that you don't have to deploy any additional files or use binding redirects to use .NET Standard 2.0 libraries.

For a demo, check out this video.

Details

While libraries targeting .NET Standard 2.0 can be consumed by applications and libraries targeting .NET Framework 4.6.1 and higher, not all files that are required for .NET Standard libraries were part of .NET Framework 4.6.1. In fact, .NET Framework 4.6.1 was shipped before .NET Standard 2.0 was even designed. That's why building an application targeting .NET Framework 4.6.1 (as well as 4.6.2 and 4.7) will have to deploy additional files.

  • If you use Visual Studio 2017 15.3 or higher, these files are automatically copied to the application's output folder.

  • If you use Visual Studio 2015 and use NuGet 3.6, we'll prompt you to install a support package which will handle copying the files to the output directory.

Starting with .NET Framework 4.7.1 these files no longer have to be deployed with the application -- they are built right into the .NET Framework itself.

.NET Framework 4.7.1 also adds about 200 missing APIs that were part of .NET Standard 2.0 but not actually implemented by .NET Framework 4.6.1, 4.6.2 or 4.7.

This also removes the need for binding redirects when using .NET Standard libraries on .NET Framework because the CLR automatically unifies version numbers of assemblies that are part of the platform.

@mungojam

This comment has been minimized.

Copy link

mungojam commented Sep 27, 2017

Good news. But it's unfortunate that it probably won't be available for older versions of Windows 10. That's been the case with previous .net releases that could not be deployed to 1511. It would be be good if it was available for all supported versions including Anniversary Update.

@terrajobst

This comment has been minimized.

Copy link
Member Author

terrajobst commented Sep 27, 2017

I'll forward the feedback, but I don't think we can influence the way Windows 10 is updated with respected to .NET Framework.

@mungojam

This comment has been minimized.

Copy link

mungojam commented Sep 27, 2017

Thanks, it's more that there is an installer for Windows 7/8 (which we still run too), but it doesn't support older (supported) versions of Windows 10. Seems like an arbitrary restriction, not technology related.

@mungojam

This comment has been minimized.

Copy link

mungojam commented Sep 27, 2017

As an example .net 4.7 installer here only supported Anniversary Update and beyond despite Windows 10 1511 being a supported version. 1511 is soon going out of support, so as long as Anniversary Update is also supported by 4.7.1, it will be ok.

@mungojam

This comment has been minimized.

Copy link

mungojam commented Sep 27, 2017

Looks hopeful, the early access preview was available for Anniversary Update. I expect it's ok :)

@terrajobst

This comment has been minimized.

Copy link
Member Author

terrajobst commented Sep 27, 2017

My understanding is that Windows 10 will generally not backport features to previous versions of Windows 10. Instead, it's a continuous path forward. I don't know enough about how Windows updates work, but it's completely possible that at this point it's not just policy but also a technical restriction in the way their release branches/update channels are implemented. Either way, I'll forward the feedback but based on previous discussions, I don't think we're likely to push .NET Framework 4.7.1 to earlier versions of Windows 10.

@mungojam

This comment has been minimized.

Copy link

mungojam commented Sep 27, 2017

It's no problem if it isn't pushed through Windows Update, because as you say that is linear on Windows 10. The important thing is that the installer works on supported versions, which it looks like it will from the preview.

@barnson

This comment has been minimized.

Copy link

barnson commented Sep 28, 2017

FWIW, it is a technology limitation, not just an arbitrary one.

@mungojam

This comment has been minimized.

Copy link

mungojam commented Sep 28, 2017

@henkmollema

This comment has been minimized.

Copy link

henkmollema commented Sep 28, 2017

@terrajobst I was trying out the native support for .NET Standard 1.3 in .NET Framework 4.6.1. It works as you described when I reference a .NET Standard 1.3 library from a .NET 4.6.1 app. However, if the library targets both .NET Standard 1.3 and 2.0 it restores the 2.0 version which pulls in all the assemblies from .NET Standard 2.0. Is there a way to configure this? (beside updating to .NET 4.7.1 😄)

@terrajobst

This comment has been minimized.

Copy link
Member Author

terrajobst commented Sep 29, 2017

@henkmollema

However, if the library targets both .NET Standard 1.3 and 2.0 it restores the 2.0 version which pulls in all the assemblies from .NET Standard 2.0.

That is expected behavior and follows the developer's intuition. Let's say you're targeting .NET Framework 4.6 and you reference a NuGet package that supports both .NET Framework 4.0 and 4.5. You'd expect NuGet will use the .NET Framework 4.5 library as it's closer to what you're targeting and likely has more features. Since we changed NuGet to consider .NET Framework 4.6.1 as implementing .NET Standard 2.0 it will now prefer 2.0, 1.6, and 1.5 over 1.4. There is (AFAIK) no way to configure this differently.

@lextm

This comment has been minimized.

Copy link

lextm commented Oct 2, 2017

@terrajobst I can see that NuGet guys have a test site to illustrate how NuGet algorithm picks up the final assembly. It should be made more obvious to developers, so you don't need to answer a million times.

I learned it from here and hope such useful information can be promoted to the documentation instead of hiding in comments.

@henkmollema

This comment has been minimized.

Copy link

henkmollema commented Oct 2, 2017

@terrajobst makes sense, thanks! 👍

@Hlynsson

This comment has been minimized.

Copy link

Hlynsson commented Oct 13, 2017

Is there an estimated release date for 4.7.1?

@dasMulli

This comment has been minimized.

Copy link
Contributor

dasMulli commented Oct 13, 2017

Reading through dotnet/sdk#1647 it doesn’t seem that 4.7.1 fixes all issues, are the assemblies mentioned there still causing a need for binding redirects?

@terrajobst

This comment has been minimized.

Copy link
Member Author

terrajobst commented Oct 13, 2017

@Hlynsson

Is there an estimated release date for 4.7.1?

Don't think we announced a date yet, but it's very soon.

@ryanelian

This comment has been minimized.

Copy link

ryanelian commented Oct 19, 2017

When I changed TargetFramework to net471 in my net462 project, this happens:

Error	CS8137	Cannot define a class or member that utilizes tuples because the compiler required type 'System.Runtime.CompilerServices.TupleElementNamesAttribute' cannot be found. Are you missing a reference?

Error	CS8179	Predefined type 'System.ValueTuple`2' is not defined or imported

Warning	MSB3277	Found conflicts between different versions of the same dependent assembly that could not be resolved.  These reference conflicts are listed in the build log when log verbosity is set to detailed.

How to fix this?

@Petermarcu

This comment has been minimized.

Copy link
Member

Petermarcu commented Oct 19, 2017

@AlexGhiondea

This comment has been minimized.

Copy link
Member

AlexGhiondea commented Oct 19, 2017

@dsplaisted @jcouv is this a known issue?

@jcouv

This comment has been minimized.

Copy link
Member

jcouv commented Oct 19, 2017

@ryanelian could you repro the error with msbuild /bl theProject.csproj and share the resulting binary log?

@ryanelian

This comment has been minimized.

Copy link

ryanelian commented Oct 19, 2017

@terrajobst

This comment has been minimized.

Copy link
Member Author

terrajobst commented Oct 19, 2017

@ryanelian

Thanks! Looks like you have a reference to the System.ValueTuple 4.3.0 NuGet package. Could try whether upgrading to 4.4.0 solves the issue?

@ryanelian

This comment has been minimized.

Copy link

ryanelian commented Oct 19, 2017

Nope, I don't have reference to that NuGet Package in my csproj:

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>net471</TargetFramework>
    <TypeScriptToolsVersion>2.6</TypeScriptToolsVersion>
    <TypeScriptCompileBlocked>true</TypeScriptCompileBlocked>
    <UserSecretsId>TAM_Passport</UserSecretsId>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Accelist.SDK.CoreMvc" Version="0.12.0" />
    <PackageReference Include="Accelist.SDK.SQL" Version="0.12.0" />
    <PackageReference Include="Accelist.SDK.PWDB" Version="0.2.0" />
    <PackageReference Include="BCrypt.Net-Core" Version="1.4.0" />
    <PackageReference Include="jose-jwt" Version="2.4.0" />
    <PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.1.1" />
    <PackageReference Include="Microsoft.AspNetCore" Version="2.0.0" />
    <PackageReference Include="Microsoft.AspNetCore.Authentication.Cookies" Version="2.0.0" />
    <PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.0.0" />
    <PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.ViewCompilation" Version="2.0.0" PrivateAssets="All" />
    <PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.0.0" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="2.0.0" PrivateAssets="All" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="2.0.0" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="2.0.0" />
    <PackageReference Include="Microsoft.VisualStudio.Web.BrowserLink" Version="2.0.0" />
    <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.0.0" PrivateAssets="All" />
    <PackageReference Include="Serilog.Exceptions" Version="2.5.0" />
    <PackageReference Include="Serilog.Extensions.Logging" Version="2.0.2" />
    <PackageReference Include="Serilog.Sinks.RollingFile" Version="3.3.0" />
    <PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="5.1.4" />
  </ItemGroup>
  <ItemGroup>
    <DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.0" />
  </ItemGroup>
  <ItemGroup>
    <ProjectReference Include="..\TAM.Passport.Entities\TAM.Passport.Entities.csproj" />
  </ItemGroup>
  <ItemGroup>
    <Reference Include="System.DirectoryServices" />
    <Reference Include="System.DirectoryServices.AccountManagement" />
  </ItemGroup>
  
</Project>

Adding System.ValueTuple 4.4.0 from NuGet does solve the problem partially, as I'm still getting this warning message:

Warning MSB3277 Found conflicts between different versions of the same dependent assembly that could not be resolved. These reference conflicts are listed in the build log when log verbosity is set to detailed.

How to make this message disappear?

I thought the new .NET Framework 4.7.0 does not need System.ValueTuple being added to the project manually? (At least I don't have to when using .NET Framework 4.6.2)

  • net462, without System.ValueTuple package reference = build successful
  • net47, without System.ValueTuple package reference = build successful
  • net471, without System.ValueTuple package reference = build error
  • net471, with System.ValueTuple package reference = build successful with warning

What is going on?

@terrajobst

This comment has been minimized.

Copy link
Member Author

terrajobst commented Oct 19, 2017

@ryanelian

Could you attach an MSBuild binary log for a build with the 4.4.0 version as well? I'd love to see the actual conflicts reported by MSBuild.

Also, if you add these settings to your project file, does it solve the problem?

<PropertyGroup>
    <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
    <GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
</PropertyGroup>

What's the output of dotnet --info?

/cc @dsplaisted

@ryanelian

This comment has been minimized.

Copy link

ryanelian commented Oct 20, 2017

msbuild.zip

btw, just curious, how do you 'see' the content of the binary log?

No, adding those lines does not make the warning message disappear...

.NET Command Line Tools (2.0.2)

Product Information:
 Version:            2.0.2
 Commit SHA-1 hash:  a04b4bf512

Runtime Environment:
 OS Name:     Windows
 OS Version:  10.0.16299
 OS Platform: Windows
 RID:         win10-x64
 Base Path:   C:\Program Files\dotnet\sdk\2.0.2\

Microsoft .NET Core Shared Framework Host

  Version  : 2.0.0
  Build    : e8b8861ac7faf042c87a5c2f9f2d04c98b69f28d
@jcouv

This comment has been minimized.

Copy link
Member

jcouv commented Oct 20, 2017

@ryanelian You can view the contents of binary logs with the structured log viewer. If you're used to msbuild logs in text format, you're in for a treat ;-)

@jcouv

This comment has been minimized.

Copy link
Member

jcouv commented Oct 20, 2017

Let's move the troubleshooting with @ryanelian and @terrajobst to separate issue: #543

@conficient

This comment has been minimized.

Copy link

conficient commented Apr 5, 2018

The experience I've had integrating .NET Standard 2.0 libraries into .NET 4.7.1 libraries suggests this is far from complete, @terrajobst

I took existing 4.6 library and upgraded to 4.7.1, but when I imported a .NET Standard nuget package, a lot of the facade library references added were broken

Warning The referenced component 'Microsoft.Win32.Primitives' could not be found.
Warning The referenced component 'System.IO.FileSystem' could not be found.
Warning The referenced component 'System.Security.Cryptography.X509Certificates' could not be found.
Warning The referenced component 'System.Globalization.Calendars' could not be found.
Warning The referenced component 'System.Security.Cryptography.Encoding' could not be found.
Warning The referenced component 'System.Security.Cryptography.Primitives' could not be found.
Warning The referenced component 'System.IO.Compression.ZipFile' could not be found.
Warning The referenced component 'System.Console' could not be found.

This happens in every C# 4.7.1 library I imported them into. Oddly the VB.NET 4.7.1 libraries didn't seem to be affected.

Second issue I encountered was that these references can also cause build errors in Release mode if the library has a webservice reference. This seems to be a known issue: dotnet/sdk#1630 -it's been around since 4.6.1 and requires hacks to the .csproj file to get them to compile.

Let's hope 4.7.2 can fix this mess!

@Gonnagle

This comment has been minimized.

Copy link

Gonnagle commented Aug 2, 2018

Could the documentation be improved to emphasize that 4.7.1 is the first framework actually fully implementing 2.0?

At least my current understanding is that the claimed support in 4.6.1 has some issues and using packages targeting netstandard 2.0 there might need additional steps (for example #481). Would be useful to have some note about this on that page.

Edit: Apparently that request is being discussed here: dotnet/docs#5915

@voltcode

This comment has been minimized.

Copy link

voltcode commented Nov 5, 2018

Does the "open" status of this ticket mean that 4.7.1 does not offer built-in support for netstandard2.0 ? If yes, then is there a ,net framework version that offers such support ? If not then which version aims to fulfil this goal?

@voltcode

This comment has been minimized.

Copy link

voltcode commented Nov 6, 2018

Can someone please answer my question? We're about to plan our steps towards netstandard and ,NETCore, the next .Net FX bump is important for us to target right so we don't have wasted work in the process. I'm not sure whether 4.7.1 is the right one considering this issue, whether 4.7.2 is better or maybe we should wait for 4.8 just in case?

@poimis

This comment has been minimized.

Copy link

poimis commented Nov 6, 2018

@voltcode If you are moving to netstandard and netcore, why are you interested in 4.7.1?

Yes, you can use netstandard libraries with 471 application code.

If you are changing target frameworks right now, go to 472 as it has some improvements over 471 considering netstandard support. In this regard, there is no reason to wait for 4.8

@voltcode

This comment has been minimized.

Copy link

voltcode commented Nov 6, 2018

@poimis We're on 4.6.2 atm that has known issue of injecting a lot of additional libraries, so the netstandard support is not clean. We want to make the transition to netstandard easier, so we want to bump the version up to reduce the amount of artifacts flying around. The problem is, I'm not certain that 4.7.1 built-in support for netstandard is completed, because this issue is still open. Are there outstanding issues with 4.7.1 and netstandard support that prevent this issue from being closed?

@poimis

This comment has been minimized.

Copy link

poimis commented Nov 6, 2018

@voltcode As this is an announcement issue, I don't think the open status has much relevance.
If you are migrating from 462, there is no reason to stick with 471, as 472 has already been released. And it has some fixes for NS support (see: https://github.com/Microsoft/dotnet/blob/master/releases/net472/dotnet472-changes.md)

@voltcode

This comment has been minimized.

Copy link

voltcode commented Nov 6, 2018

@poimis do you know if 4.7.2 status of netstandard20 is complete with regard to problems with additional dlls, etc. ?

@poimis

This comment has been minimized.

Copy link

poimis commented Nov 6, 2018

It was the case already with 471. It only had some problems with some workarounds #567 that are supposed to be fixed in 472.

@AlexGhiondea

This comment has been minimized.

Copy link
Member

AlexGhiondea commented Nov 8, 2018

@voltcode if you are considering moving from 462 to a newer version, I recommend 472. When targeting 472 there will be no additional libraries necessary when you are using .NET Standard 2.0 libraries.

@joaocpaiva

This comment has been minimized.

Copy link

joaocpaiva commented Nov 12, 2018

My team is evaluating whether to take a new dependency that carries over a few assemblies built off .NET Standard 2.0. At this time we still run on .NET 4.6.2 and upgrading to 4.7.1 is not a trivial option. Is there a tool to sweep for the missing APIs, to ensure we can safely consume the new .NET Standard 2.0 assemblies?

@gaui

This comment has been minimized.

@rolix7

This comment has been minimized.

Copy link

rolix7 commented Jan 4, 2019

Is it possible to disable the following behavior:

If you use Visual Studio 2017 15.3 or higher, these files are automatically copied to the application's output folder.

@joperezr

This comment has been minimized.

Copy link
Member

joperezr commented Jan 4, 2019

@rolix7 There is a property that can override copying them, but most likely your app will stop working on some machines if you set this property. The files get placed there for a reason, we put them there since your app will most likely need them at runtime when running on the framework you are targeting. It might be that locally you see that you don't need them, but that is only because you might have a higher version of the framework than the one your app is targeting. If you don't want to see these extra files, it is better to target .NET Framework 4.7.2 where no extra files will be copied to your bin folder since they won't be required at runtime.

@rolix7

This comment has been minimized.

Copy link

rolix7 commented Jan 4, 2019

@joperezr Thanks for your response! We are already checking, if it's possible for us to migrate to .NET Framework 4.7.2. But since this could possibly be not the case, can you please tell me what property that is?

@joperezr

This comment has been minimized.

Copy link
Member

joperezr commented Jan 4, 2019

@rolix7 the property is DependsOnNETStandard and you will have to set it to false. IT IS VERY IMPORTANT TO UNDERSTAND THAT THIS WILL BREAK PEOPLE RUNNING YOUR APP. Those extra files are REQUIRED for people that tries to run your app in anything lower than 4.7.2, so if you have any consumer/customer running your application in 4.6.1 - 4.7.1 they will most likely encounter runtime errors for types not found, or members not found, or assembly load exceptions. Only people running your app in 4.7.2 will be able to run the app successfully.

@rolix7

This comment has been minimized.

Copy link

rolix7 commented Jan 9, 2019

@joperezr Let's say we migrate our projects to .NET 4.7.2, then our current problems should be solved, right? What if a newer version of the entity framework core (or another third party package), which we depend on, is targeting a newer .NET Standard (2.0+) version. Will we get the same problems again?

Thanks in advance!

@amartens181

This comment has been minimized.

Copy link

amartens181 commented Jan 9, 2019

@rolix7 technically 4.6.2 supports standard 2, but yes, you will face the same thing later... Considering 4.8 will never support more than standard 2, the next one will have to be .net core

@joperezr

This comment has been minimized.

Copy link
Member

joperezr commented Jan 9, 2019

Let's say we migrate our projects to .NET 4.7.2, then our current problems should be solved, right?

Correct, by targeting 4.7.2 then you will be ensuring that only people with 4.7.2 installed would be able to run your app which means that: 1) you won't need the extra files so they won't get copied to your bin folder, and 2) You won't need the property at all, our tooling will do the right thing and won't copy those files around.

What if a newer version of the entity framework core (or another third party package), which we depend on, is targeting a newer .NET Standard (2.0+) version. Will we get the same problems again?

At least as of now, I don't know if newer versions of .NET Standard will be compatible by other versions of .NET Framework so that is hard to say, for now, if you target 4.7.2 you should be able to use any package that targets .NET Standard 2.0 without any problems. It is worth to note that the current guidance for library and package developers is to always target .NET Standard 2.0 if they intend their library to run on .NET Framework, as it is not yet defined if newer versions of the standard will be able to run in .NET Framework at all.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment