What's the difference between <TargetFramework> and <RuntimeFrameworkVersion>?

30,916

Solution 1

The TargetFramework is used by NuGet to resolve dependencies and determine the assets to be used for compiling and building the application. (Behind the scenes, a few more properties like TargetFrameworkMoniker and TargetFrameworkVersion come into play but the SDK abstracts it to a simpler TargetFramework for frameworks it knows about).

The RuntimeFrameworkVersion is specific to .NET Core / netcoreapp. The SDK will inject a dependency on Microsoft.NETCore.App for the version that RuntimeFrameworkVersion is set to or use the latest version it knows about for .NET Core < 2.0. The resolved version is then written to the runtimeconfig.json file for the .NET Core host framework resolver to resolve the version of the shared framework to load (=> .NET Core 1.1.4 runtime for example).

The reason you are able to use 1.1.* for netcoreapp1.0 is because the NuGet package actually contains the necessary assets to build .NET Core 1.0.* applications. However the tooling doesn't know this so you'll get a .NET Core 1.0 app but it will be loaded by the 1.1 framework because that's what ends up in the runtimeconfig.json file.

The important difference is:

  • It only matters for self-contained executables which version of Microsoft.NETCore.App is used.
    • This package will pull in the complete framework with the desired version when performing a self-contained publish (e.g. dotnet publish -r win7-x64)
    • When you run an application built for 1.0.3 but you have the 1.0.5 runtime installed, the 1.0.5 runtime will be used automatically.
    • If you don't set RuntimeFrameworkVersion and a new version of the SDK is released that knows about newer patch versions of .NET Core, it will use the newest version automatically. If you set the version explicitly, you may not be up-to-date without editing the project file.
  • The RuntimeFrameworkVersion is also the minimum runtime that the application will load - if you set it to 1.0.4 and try to run on a machine that only has 1.0.3 installed, the application will not start unless you edit the runtimeconfig.json file.
  • RuntimeFrameworkVersion can be set to a floating version, which is useful when targeting preview versions or daily builds, e.g. 2.1.0-preview1-* would resolve to the newest preview1 version available on the configured NuGet feeds.

Apart from these, there are only a few reasons to build using a higher version of Microsoft.NETCore.App, like a build bugfix for the DiaSymReader component.

In .NET Core 2.0, the version of RuntimeFrameworkVersion will always be 2.0.0 for "portable applications" (non-self contained) because the implementation of the framework is no longer provided by the dependencies of Microsoft.NETCore.App and this NuGet package is only used to provide reference assemblies for compilation.

Solution 2

From the docs, you should use runtimeframeworkversion only

If you need a specific version of the runtime when targeting .NET Core, you should use the property in your project (for example, 1.0.4) instead of referencing the metapackage.

https://docs.microsoft.com/en-us/dotnet/core/tools/csproj

Share:
30,916

Related videos on Youtube

8protons
Author by

8protons

Just trying to figure things out.

Updated on July 09, 2022

Comments

  • 8protons
    8protons almost 2 years

    I have the following code in a csproj file:

    <TargetFramework>netcoreapp1.0</TargetFramework>
    

    In the NuGet package manager, it says that I have Microsoft.NETCore.App version 1.0.5

    Now let's say I have the following code in the same csproj file:

    <TargetFramework>netcoreapp1.0</TargetFramework>
    <RuntimeFrameworkVersion>1.1.4</RuntimeFrameworkVersion>
    

    The NuGet package manager will now say that I have Microsoft.NETCore.App version 1.1.4

    I'm essentially trying to use the latest framework before .NETCore 2.0 (having some EF issues when I converted) which would be .NETCore 1.1.4, but the multiple Framework attributes in csproj make me unsure which tag to use. I was unable to find any resources that clearly distinguishes the differences between the two.

  • Martin Ullrich
    Martin Ullrich over 6 years
    RuntimeFrameworkVersion should only be used when a specific version of the Microsoft.NETCore.App package is needed. There are only a limited number of use cases where you would actually want to do this.
  • 8protons
    8protons over 6 years
    If I comment out my TargetFramework tag, I get the following error in my Microsoft.NET.TargetFrameworkInference.targets file: "The TargetFramework value '' was not recognized. It may be misspelled. If not, then the TargetFrameworkIdentifier and/or TargetFrameworkVersion properties must be specified explicitly"
  • 8protons
    8protons over 6 years
    So what is the actual consequence of having both attributes as in my code sample above? The RuntimeFrameworkVersion tag clearly dictates with NuGet sees, taking priority over the TargetFramework tag. Yet if I omit the TargetFramework tag, the project fails to build with The TargetFramework value '' was not recognized. It may be misspelled. If not, then the TargetFrameworkIdentifier and/or TargetFrameworkVersion properties must be specified explicitly.
  • Martin Ullrich
    Martin Ullrich over 6 years
    The target framework specifies the slice of the package that is used for compilation. So if you write foobar1.0, it won't work. Also, RuntimeFrameworkVersion is specific to the netcoreapp target framework
  • Neutrino
    Neutrino over 5 years
    Does this mean that RuntimeFrameworkVersion in a netstandard2.0 class library has no effect at all, or in a self contained application does this still enforce a minimum runtime version for the componnet in the same way that it does for an executable?
  • Martin Ullrich
    Martin Ullrich over 5 years
    netstandard2.0 is not coupled to a runtime, so it will have no effect on an application consuming it.
  • willem
    willem over 4 years
    This article also provides a good explanation: docs.microsoft.com/en-gb/dotnet/core/versions/selection. Helped me understand this particular answer.