question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Enable projects to use the SDK `TargetFramework`

See original GitHub issue

The .NET SDK comes with a targeting pack and a runtime (in addition to build tools). If you compile an app for the same version as the SDK, then you can use the targeting pack and runtime that comes with the SDK. Yeahh! If you compile an app for an older version, then you need an older version of the runtime and targeting pack. You can either install those or update the project file. There is no way to that via the commandline. You can change the RID via the commandline but not the TFM.

The .NET SDK offers a variety of controls for controlling compile-time vs runtime framework versions. The model, however, could be better. This is particularly obvious if you are wanting to test existing/old apps on a newer SDK.

FYI: I’m using older .NET versions for my examples, only because they were convenient. This experience hasn’t changed recently.

This is the base experience today, when SDK and TargetFramework don’t match:

root@3ed29927af5a:/core/samples/dotnet-runtimeinfo# dotnet --version
6.0.113
root@3ed29927af5a:/core/samples/dotnet-runtimeinfo# dotnet run
You must install or update .NET to run this application.

App: /core/samples/dotnet-runtimeinfo/bin/Debug/netcoreapp3.1/dotnet-runtimeinfo
Architecture: x64
Framework: 'Microsoft.NETCore.App', version '3.1.0' (x64)
.NET location: /usr/lib/dotnet

The following frameworks were found:
  6.0.13 at [/usr/lib/dotnet/shared/Microsoft.NETCore.App]

You cannot updated TargetFramework from the commandline, AFAICT.

root@3ed29927af5a:/core/samples/dotnet-runtimeinfo# cat dotnet-runtimeinfo.csproj | grep TargetFramework
    <TargetFramework>netcoreapp3.1</TargetFramework>
root@3ed29927af5a:/core/samples/dotnet-runtimeinfo# dotnet run -p:TargetFramework=net6.0
/usr/lib/dotnet/sdk/6.0.113/Sdks/Microsoft.NET.Sdk/targets/Microsoft.PackageDependencyResolution.targets(267,5): error NETSDK1005: Assets file '/core/samples/dotnet-runtimeinfo/obj/project.assets.json' doesn't have a target for 'net6.0'. Ensure that restore has run and that you have included 'net6.0' in the TargetFrameworks for your project. [/core/samples/dotnet-runtimeinfo/dotnet-runtimeinfo.csproj]

The build failed. Fix the build errors and run again.

The RollForward property works pretty well. It can be added to a project file or injected via ENV or the CLI (via -p:RollFoward). RollForward model has the downside that an old target framework needs to be downloaded, at least in the case that you want to use a new SDK for both compiling and running the app.

Instead, it would nice if there was a way to say “roll forward by using the SDK target framework”. That would result in using SDK-provided assets and to naturally using the SDK runtime version.

We could offer a way to specify what the minimum target framework is for a project and infer the actual target framework from the SDK (assuming it is same or higher). That way, you wouldn’t ever get weird compile-time failures due to missing APIs.

Perhaps via the following property:

<MinimumTargetFramework>net6.0</MinimumTargetFramework>

or possibly:

<TargetFramework>net6.0</TargetFramework>
<UseSdkTargetFramework>true</UseSdkTargetFramework>

The second property could also be UseSdkDefaults if we wanted something more general.

This approach would have a few benefits:

  • The SDK version would become the primary version concept to reason about (for folks that adopted this model).
  • The (minimum) TargetFramework property would solely describe API surface area, as opposed to also determining minimum runtime version.
  • The SDK-provided targeting pack would be used, skipping an extra download.
  • The RollForward property wouldn’t need to be used as part of development, leaving it only for deployed apps.

Some apps would break with this model, either due to breaking changes, warning waves or something else. It’s less about the apps breaking and more about the care factor of the apps breaking. There are two solutions for that: don’t use the feature, or use global.json. For people that use global.json, this feature would still have significant value.

This model would be more complicated for compound TFMs, like the ones we have for Android and iOS. That would require some more thought. I thought we should start out with the base premise before looking at those TFMs.

This model wouldn’t work (at least not naturally) with multi-targeting. That seems fine, both because multi-targeting is uncommon with apps and because multi-targeting is an intentional model that isn’t amenable to policy solutions like this.

Issue Analytics

  • State:open
  • Created 8 months ago
  • Comments:11 (10 by maintainers)

github_iconTop GitHub Comments

1reaction
richlandercommented, Jan 31, 2023

Perhaps we should put a version number at the top:

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

  <PropertyGroup>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
  </PropertyGroup>

</Project>

That completes the pivot. The 8.0 would be a minimum.

Or better yet:

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

</Project>

Obviously, there might be an ItemGroup here.

@mhutch @DamianEdwards

0reactions
richlandercommented, Feb 1, 2023

Yes. Certainly, whether it is opt-in min or exact is a detail.

There are really two suggestions here:

  • Simplify project files by making SDK type the key concept.
  • Enable the min version idea through some variation of that.
Read more comments on GitHub >

github_iconTop Results From Across the Web

Target frameworks in SDK-style projects - .NET
When you target a framework in an app or library, you're specifying the set of APIs that you'd like to make available to...
Read more >
MSBuild reference for .NET SDK projects
Use the TargetFrameworks property when you want your app to target multiple platforms. For a list of valid target framework monikers, see Target ......
Read more >
Target Multiple Frameworks in .NET Core 2.x App
The first step is to create a new project in Visual Studio 2017 by clicking on File -> New Project.. This will open...
Read more >
Target Framework .Net Core 3.0 not available
I've just updated Visual studio to 15.9.2. I've been working on a project which was using .Net core 3 preview framework.
Read more >
Cannot Change Target Framework?
A modern class library should use multiple target frameworks today, which means the options can only be set in project files right now,...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found