Remove support for the implicit package version of Microsoft.AspNetCore.App
See original GitHub issueMicrosoft.AspNetCore.App, unlike normal NuGet packages, represents a shared framework. This means the package provides:
- A) The minimum expected version of of the ASP.NET Core shared runtime (found in C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App$(PackageVersion))
- B) A baseline of assemblies versions which the SDK expects to find in the shared runtime
- C) References assemblies for the compiler
- D) Implementations assemblies for self-contained deployments
There is tension between these as we want the lowest possible version of (A) to simplify deployment concerns, the highest version of (D) for security updates and patch fixes, and a version of (B) and © compatible with both (A) and (D).
We attempted to solve this tension in 2.1.0 by optimizing for (A) and hiding the package version from users and keeping it low, pinned to 2.1.0. That made it difficult to use packages which shared dependencies with the shared framework. In 2.1.1, we tried to fix this by easing off the restrictions and allowing package upgrades, but means users unintentionally upgrade out of the baseline (B), and end up with redundant copies of binaries in their publish output.
After lots of design discussion reviewing half a dozen alternatives, we think it will be better in the long run to back to reverse course and encourage users to use an explicit version on the PackageReference to Microsoft.AspNetCore.App, and it regularly update it to latest.
Proposed changes
-
Update
dotnet new
templates to include the latest Microsoft.AspNetCore.App package version in the .csproj file. -
Update Microsoft.NET.Sdk.Web to warn when Microsoft.AspNetCore.App is missing a package version.
- Text:
The package reference to Microsoft.AspNetCore.App is missing the Version attribute. Defaulting to Version="2.1.1".
.
- Text:
-
Remove “IsImplicitlyDefined” = true from Microsoft.NET.Sdk.Web. This unblocks the NuGet UI from displaying updates. Before:
After:
Downsides
One of the primary reasons for making the version implicit was to simplify deployment. As history since 2.0.0 has taught us, our users that updating a PackageReference should be sufficient to use the newest version of ASP.NET Core. However, there is one more step required: users need to install a compatible shared runtime. This step is not obvious from the NuGet Package UI in VS, and error messages indicating the missing runtime are sometimes hidden (e.g. IIS Express, Test Explorer).
Proposed enhancement
[Nate: July 9]: this was not implemented, and we are not planning to implement right now.
- Update Microsoft.NET.Sdk to produce a warning when compiling for a .NET Core shared framework which is not present on the machine (cc @dsplaisted @nguerrera).
- Text:
This project is compiling for Microsoft.AspNetCore.App 2.1.3, but a compatible runtime was not found. .NET Core runtimes can be installed from https://aka.ms/dotnet-download
- Text:
Issue Analytics
- State:
- Created 5 years ago
- Comments:44 (35 by maintainers)
The reason I disagree with your disagree:) is for the shared runtime it conflates the concept of a NuGet package that is included with your package bundle created at build time and a runtime where the version isn’t known until deployment time.
For the sake of conversation I’m ignoring the implicit version case. I believe we are in agreement that that is a bad practice since that was why this issue was open and I apologize for the conversation going well passed the original intent of the issue. In our upcoming Lambda tooling for .NET Core we will require a version being set so we can verify compatibility.
Now back to package version being the decider of runtime version. There is nothing about the following section that indicates to to the developer that if you change 2.1.0 to 2.1.1 They need to make sure their deployment target has 2.1.1 prebaked in it.
As a .NET developer I’m trained to think that dotnet publish will create me a portable package bundle that will work in any .NET Core 2.1 execution environment.
What I see happening is .NET developers are going to run into some problem that they think is due to the version of libraries so in Visual Studio they will see that have a half dozen dependencies that are slightly out of date so they go and upgrade them all thinking they now have all of the latest bug fixes. Unwittingly they have now upgrade their runtime version and their deployments are failing for a new reason. Whats worse is often the deployment happens days later so they forget about the reference update. This is what happened to us all of the time in the .NET Core 1.x days and I spent so much time debugging developers project files.
Now luckily the error message in this case is better but you still have to figure out what caused the package bundle to require a newer runtime.
After lots of discussion and experimentation, I’m closing this issue as we do not plan to make changes in 2.1 or 2.2 to address this issue. We are going to stick with original design; versionless PackageReference is the recommended way to use Microsoft.AspNetCore.App. I will update our docs and guidance to match this recommendation.
We implemented and tested alternatives ways to reference the Microsoft.AspNetCore.App shared framework. While these might have been accepted if we had done them in the first place, we did not feel benefits of switching approaches outweighed the costs. This was especially true as we began to design 3.0. In 3.0, we plan to rework the way shared frameworks are referenced in projects. Rather than introducing more churn, we’re going to make some improvements in the 2.2 SDK for using the versionless PackageReference (see https://github.com/dotnet/sdk/pull/2533), and will focus our efforts on making 3.0 better. We’ll share more details about our plans for 3.0 soon.
cc @DamianEdwards