United Kingdom: +44 (0)208 088 8978

Specifying .NET versions

Matt shows how you can control the SDK used for .NET CLI commands, and the runtime used to host your app.

We're hiring Software Developers

Click here to find out more

Controlling SDK version

If you have ever used the SAFE Template to create a new SAFE application, you may have noticed that there is a global.json file at the project root. The global.json file is used to specify which .NET SDK to use when executing CLI commands. At time of writing, the default SAFE Template's global.json file specifies that the latest 5.* SDK should be used when running .NET CLI commands within the repository.

{
  "sdk": {
    "version": "5.0.100",
    "rollForward": "latestMinor"
  }
}

The version property specifies the lowest SDK version that is permissible. The rollForward property specifies which later SDK versions are also permissible, and which to use if there are multiple permissible options. The latestMinor policy indicates that any SDK matching the specified major version (5) is permissible, and the latest available one should be used. Other options include minor (use the specified major version and match the rest as closely as possible), latestMajor (use the latest version) and disable (only use the specified version). Full details can be found in the global.json overview.

If you have multiple SDKs installed, you can experiment (you can check your installed SDKs with dotnet --list-sdks). For example, I have SDKs 5.0.408 and 6.0.300 installed. Running dotnet --version with the above global.json gives me 5.0.408. If I change the rollForward property to latestMajor, I get 6.0.300. Using latestPatch results in an error.

A final point to note on global.json is that it's not required - if no global.json is found, CLI commands use the latest SDK installed on the machine.

Controlling runtime version

The dotnet executable hosts your application when you run it. It's possible to specify how the executable should select a runtime for your application. The concepts are similar to those used for global.json.

Firstly, .NET project files specify target frameworks using Target Framework Monikers. For example, in the SAFE Template, the TargetFramework element in the Server's project file specifies that the target framework is net5.0.

    <TargetFramework>net5.0</TargetFramework>

You can also add the RollForward property to the project file. For example you can add the following to specify to always use the latest major and minor runtime version, so long as it is at least the minimum required by the moniker.

<PropertyGroup>
    <RollForward>LatestMajor</RollForward>
</PropertyGroup>

Together, the Target Framework Moniker and the RollForward property describe how a runtime should be selected.

I have the 5.0.17 and 6.0.5 runtimes installed (you can check yours with dotnet --list-runtimes). If I add the above property to the server project and check the runtime that is used (for example by using System.Environment.Version), I see 6.0.5. If instead I set RollForward to LatestMinor (match the specified major version, but use the latest minor version), I see 5.0.17. The default behaviour is to use the latest patch version if the requested minor version is present and otherwise to roll forward to the lowest minor version that is higher than specified.

It is also possible to control runtime roll-forward behaviour by editing the *.runtimeconfig.json file generated when your app is compiled, setting the DOTNET_ROLL_FORWARD environment variable, or setting the --roll-forward parameter of the dotnet command.

Summary

Controlling SDK and runtime versions is not the most exciting thing that you can do in .NET. However, it's useful to know about these concepts and to be aware of what's possible. If you'd like to learn more, the .NET version selection page in the Microsoft docs for .NET Core goes into more detail.