Skip to content
This repository has been archived by the owner on Sep 13, 2022. It is now read-only.

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

Closed
terrajobst opened this issue Sep 27, 2017 · 56 comments
Closed

Comments

@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
Copy link

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
Copy link
Member Author

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
Copy link

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
Copy link

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
Copy link

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

@terrajobst
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
Copy link

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
Copy link

barnson commented Sep 28, 2017

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

@mungojam
Copy link

mungojam commented Sep 28, 2017 via email

@henkmollema
Copy link

@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
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
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
Copy link

@terrajobst makes sense, thanks! 👍

@Hlynsson
Copy link

Is there an estimated release date for 4.7.1?

@dasMulli
Copy link

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
Copy link
Member Author

@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
Copy link

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
Copy link
Member

@AlexGhiondea

@AlexGhiondea
Copy link

@dsplaisted @jcouv is this a known issue?

@jcouv
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
Copy link

msbuild.zip

@terrajobst
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
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
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
Copy link

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
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
Copy link
Member

jcouv commented Oct 20, 2017

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

@voltcode
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
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
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
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
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
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
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
Copy link

@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
Copy link

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
Copy link

gaui commented Nov 13, 2018

@rkieslinger
Copy link

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

@rkieslinger
Copy link

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

@rkieslinger
Copy link

@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
Copy link

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

@terrajobst
Copy link
Member Author

Closing as this an announcement. For the record, we've started to track issues related to .NET Framework support with this label.

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