Skip to content
This repository has been archived by the owner on Nov 21, 2018. It is now read-only.

Discussion for Introduction of new meta-package "Microsoft.AspNetCore.App" #255

Closed
DamianEdwards opened this issue Jan 30, 2018 · 32 comments

Comments

@DamianEdwards
Copy link
Member

Discussion issue for aspnet/Announcements#287

@yang-xiaodong
Copy link

I think packaging Microsoft.AspNetCore.All into the SDK is a very bad decision and one day you guys will remove them from the SDK.

@jchannon
Copy link

Microsoft.AspNetCore.All is an optional package currently. Are you saying that Microsoft.AspNetCore.App is a requirement for 2.1 apps?

@davidfowl
Copy link
Member

You can always reference individual packages.

@scottaddie
Copy link
Member

@davidfowl I'm assuming this new metapackage isn't to be used by apps targeting .NET Framework instead of .NET Core. Is that correct?

@Eilon
Copy link
Member

Eilon commented Jan 31, 2018

@scottaddie yes it's .NET Core only.

@DamianEdwards
Copy link
Member Author

@scottaddie @Eilon actually we're working with the .NET team to get the linker (trimmer) working on ASP.NET Core applications targeting .NET Framework, so that we can allow the meta-package to work on .NET Framework targeted apps too. This is currently in scope for 2.1, although will not make it for the first preview. We'll keep folks posted.

@mungojam
Copy link

mungojam commented Feb 3, 2018

Is there an explanation for the reasoning behind this change? I feel there is some interesting background missing

@DamianEdwards
Copy link
Member Author

DamianEdwards commented Feb 7, 2018

@mungojam sorry for the delay, yes indeed there is some more context I've been meaning to add. There's two main things:

  • The new meta-package doesn't contain packages that we aren't able to support and/or service (as in, forcibly release patches for e.g. in cases of critical security issues). The three that are included we were unable to remove while keeping the core products functional, but we also don't anticipate any support or servicability issues with them. In the future (like, 3.0 and beyond) we'll be taking a modified approach to how we integrate with and ship 3rd party libraries to ensure a clear story for our "default" product experience, i.e. using Microsoft.AspNetCore.App results in your app using MS-supported and servicable bits.
  • The other part is the new meta-package includes version restrictions, such that other packages you might bring in, can't unintentionally upgrade bits of what's in Microsoft.AspNetCore.App higher than the version included. This helps to ensure a more reliable experience, as it becomes harder to end up with untested version combinations of related bits being used together in the same app (a large cause of customer issues today, given it often happens completely silently). You'll still be able to force it in the cases you want to do so (by lifting the affected package references to be direct in your project) but at that point you're effectively in an unsupported state.

@mungojam
Copy link

mungojam commented Feb 7, 2018

@DamianEdwards thanks, those make sense.

On the second point, that's an interesting one. What if people are adding later versions for direct use in their projects but don't realise that the meta package also has a dependency on them? Hoping it would lead to a build warning.

@DamianEdwards
Copy link
Member Author

@mungojam indeed NuGet will give you a warning if you force an override of a version range restriction by hoisting the dependency. You can optionally suppress the warning I believe, but by default you'll be notified you're going outside the lines.

@MV10
Copy link

MV10 commented Mar 21, 2018

The other part is the new meta-package includes version restrictions, such that other packages you might bring in, can't unintentionally upgrade bits of what's in Microsoft.AspNetCore.App higher than the version included.

Isn't this going to lead to the same hassles the Azure Functions team is struggling with due to binding redirects? Using any recent version of something as crucial as JSON.NET with Functions v1 is currently very troublesome due to a hard dependency on an old version:

Azure/azure-functions-host#992

@DamianEdwards
Copy link
Member Author

The restrictions are only applied to our packages, so don't include JSON.NET. Also this is all in your project, so you're in complete control of the overrides if you wish, unlike the situation on Azure Functions where you don't control the host and thus can't unify versions via assembly redirects.

@MV10
Copy link

MV10 commented Mar 21, 2018

Gotcha. So it's more a case of, "I'm using ASP.NET Core 2.1.3, so I'm expected to add config extensions 2.1.3," or whatever specific version is defined, rather than "grab the latest and hope it works."

@mholec
Copy link

mholec commented May 6, 2018

There is many Microsoft.EntityFrameworkCore.Xxxxx dependencies in this metapackage. In my opinion:

  1. In most projects, it is not typical to have referenced ORM in the ASP.NET Core web project (which have mostly "presentation layer" purpose).
  2. If I want to use EF Core in class library, I have to reference all EF Core packages. What about to create dependency package - something like Microsoft.EntityFramework.All?

Related issue: dotnet/efcore#11920

@shep1987
Copy link

shep1987 commented May 8, 2018

I also had to add a reference to Microsoft.AspNetCore.AzureAppServicesIntegration after swapping to .App

@rguerreiro
Copy link

@DamianEdwards how are you on supporting this meta-package for the .NET Framework? I'm in the works to change a current ASP.NET Core 2.1 (rc1) to .NET Framework in order to host it inside a windows service. But until now I'm getting the error that the Microsoft.AspNetCore.App is not compatible with net471.

Will this work for the RTM? If not, how do you advice on bypassing it? Remove the reference to the AspNetCore.App meta-package and reference the packages individually?

@davidfowl
Copy link
Member

No the meta package doesn’t support .NET Framework and it won’t for RTM. We don’t have a good way trim the package so your bin folded would contain hundreds of packages.

@rguerreiro
Copy link

@davidfowl so what's the best way to self-host a 2.1 asp.net core web app? I know that a windows service was the recommended way, but it seems that now it won't be possible. Feel free to point me to another project to ask this question.

@markusschaber
Copy link

@rguerreiro
Copy link

@markusschaber yes it's true, but since the meta-package Microsoft.AspNetCore.App (which is the recommended package to use from 2.1 onward) is not supported with the .NET Framework (and won't be in the near future) I'm not able to convert my current web app from netcoreapp2.1 to net471 which is a step needed to run it as a windows service (as you can see here)

@markusschaber
Copy link

@rguerreiro AFAICS, the meta-package just pulls in other packages transitively, it has no content on its own.

So it should be possible to just reference the required nuget Packages directly.

@poke
Copy link
Contributor

poke commented Jun 4, 2018

@rguerreiro

I'm not able to convert my current web app from netcoreapp2.1 to net471

No, you just won’t be able to use the shared framework or meta package. Just reference what you need directly instead. So instead of this:

<PackageReference Include="Microsoft.AspNetCore.App" />

You do this:

<PackageReference Include="Microsoft.AspNetCore" Version="2.1.0" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.Cookies" Version="2.1.0" />
<PackageReference Include="Microsoft.AspNetCore.Identity" Version="2.1.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.1.0" />
… and whatever else you need

Metapackages and the shared framework are completely optional. You can always choose to reference your dependencies explicitly instead. That will work on both the full framework and .NET Core.

@Tratcher
Copy link
Member

Tratcher commented Jun 4, 2018

.NET Framework is not required to run in a windows service, netcoreapp2.1 should work fine.

@rihei
Copy link

rihei commented Jun 19, 2018

If I have understood correctly, the Microsoft.AspNetCore.App package is included in the runtime, so the runtime and the App package always have the same version number.
And the runtime version depends on project file's TargetFramework and possible RuntimeFrameworkVersion, plus what versions are installed in the host environment.

Some questions:

a) How should I select the version for those App-package included packages that I also need in other projects of the same solution?
I have some class libraries that the web app depends on, so do I need to know the exact version of runtime to be able to reference the same version of the common packages in the class libraries? (for example Microsoft.EntityFrameworkCore)

b) What if a newer runtime gets installed to the host? Then the web app references a newer version of the same package than the class library. For example Microsoft.AspNetCore.App v2.1.0 requires the Microsoft.EntityFrameworkCore to be exactly version 2.1.0. (This is different from 2.1.1, which requires most packages to be at least 2.1.1 and less than 2.2.0.)

c) What are the best practices to specify version numbers of the SDK and runtime? For example, I have a web app hosted in Azure App Services, and some class libraries that the web app depends on. Should I always...

  • specify the SDK version in the global.json
  • make sure the (VSTS hosted) build agent has the correct SDK installed (or install it myself in a build step)
  • find out which runtime versions the Azure App Service has installed (by using the Console in Azure portal and typing dotnet --list-runtimes)
  • choose some of these runtimes and specify it in all project files as the RuntimeFrameworkVersion

If I don't spec the RuntimeFrameworkVersion, the runtime might get updated, and I would have a version mismatch in the packages that are referenced both by the Microsoft.AspNetCore.App and directly from other projects.

If I do spec the RuntimeFrameworkVersion...

  • What happens if the server doesn't have this one?
    • Probably versions do not disappear from the App Services, so I should be safe if it exists there now?
    • Does the shared framework roll-forward mechanism override my RuntimeFrameworkVersion specification?
  • Apparently Azure App Service does not have the 2.1.1. yet, so I need to specify 2.1.0 as the RuntimeFrameworkVersion. When I some day later realize that the 2.1.1 is installed, I should update the RuntimeFrameworkVersion and all class library packages that are included in the Microsoft.AspNetCore.App.

..or should I even publish a self-contained application?

@rihei
Copy link

rihei commented Jun 19, 2018

And another: is it ok to reference the Microsoft.AspNetCore.App package in a class library (or a Test project) that is tightly related to the Web app? Or should I reference each required package separately?

@DamianEdwards
Copy link
Member Author

@rihei good questions!

We realized that the version constraints in Microsoft.AspNetCore.App/2.1.0 were too strict, so in 2.1.1 they've been relaxed to allow higher patch versions. When this happens, you'll end up with more assemblies in your application output however, and we're looking at making tweaks in future servicing updates to fix that too.

For your class libraries that reference the "atom" packages that are otherwise included in Microsoft.AspNetCore.App, we recommend you target the lowest matching major.minor version, e.g. 2.1.0. The application's graph will lift to the latest patch at either restore time (if the project is trying to pull in a higher patched package) or runtime (if you have the patched runtime installed).

Azure App Service will always lag slightly when it comes to releases, but for patches if you follow the above you shouldn't be broken because you're always only targeting the major.minor at build time, and relying on runtime roll forward to get onto the latest patch. Or, your referencing patched versions of "atom" packages which will end up in your output folder, so you have them with you. For total isolation though, self-contained publish is the most conservative approach. You take everything you need with you, but now you won't get the benefit of runtime updates without re-publishing your application.

Hope this helps.

@rihei
Copy link

rihei commented Jun 20, 2018

Hi!

@DamianEdwards, thank you for the answers!

A couple of things are still a bit unclear for me:

  1. Should I specify the RuntimeFrameworkVersion in project files?
  • How does specifying this affect at restore/publish/runtime?
  • If I understood correctly, running an application directly from sources treats RuntimeFrameworkVersion as the minimum version, and the runtime might roll-forward to a newer version on any application restart. But how does this work with a published application? Does RuntimeFrameworkVersion lock the runtime version, or is it the minimum, and if it's minimum then at which point can the runtime version change? Restore? Publish? Restart?
  1. What if the RuntimeFrameworkVersion and atom package versions are not compatible (for example runtime 2.1.0 and some atom package 2.1.1)? AFAIK the App package has the last word about the version, so do the atom packages v2.1.1 get downgraded when I use runtime 2.1.0? Or is it just an error?

  2. Is it good or bad to reference the Microsoft.AspNetCore.App package in a class library (or a Test project) that depends on/is depended by a web project and needs many of the same packages contained in the App package (which is already referenced by the web project)? I thought that this way I wouldn't need to think about version compatibility nor restore any new packages because the App package is already referenced from the web project.

  3. A question about the first part of your answer: Why would I have more assemblies in my output? Because of allowing patch versions of the atoms of Microsoft.AspNetCore.App package? Is it so that first I have those original atom packages that were included in the runtime's App package, and then some atoms get restored as a newer patch version, too? Because of newer references in class libraries, or just standard roll-forward behaviour (in restore/runtime)?

@davidfowl
Copy link
Member

Should I specify the RuntimeFrameworkVersion in project files?

No.

How does specifying this affect at restore/publish/runtime?

It means you need to have the target runtime installed on both your deployment environment and the development environment.

If I understood correctly, running an application directly from sources treats RuntimeFrameworkVersion as the minimum version, and the runtime might roll-forward to a newer version on any application restart. But how does this work with a published application? Does RuntimeFrameworkVersion lock the runtime version, or is it the minimum, and if it's minimum then at which point can the runtime version change? Restore? Publish? Restart?

It's a minimum. The runtime will still roll forward to the latest patch version at runtime (2.1.x where x is the highest installed patch on the target). This behavior can be disabled but that's the default.

Is it good or bad to reference the Microsoft.AspNetCore.App package in a class library (or a Test project) that depends on/is depended by a web project and needs many of the same packages contained in the App package (which is already referenced by the web project)? I thought that this way I wouldn't need to think about version compatibility nor restore any new packages because the App package is already referenced from the web project.

We recommend referencing individual packages in class libraries. Reason being that the meta package only works on .NET Core and if you want to run everywhere that ASP.NET Core runs you need to be netstandard 2.0. Test projects should reference the Microsoft.AspNetCore.App and should use the Web.SDK, I believe there's a doc on this.

A question about the first part of your answer: Why would I have more assemblies in my output? Because of allowing patch versions of the atoms of Microsoft.AspNetCore.App package? Is it so that first I have those original atom packages that were included in the runtime's App package, and then some atoms get restored as a newer patch version, too? Because of newer references in class libraries, or just standard roll-forward behaviour (in restore/runtime)?

Because the 2.1.0 shared framework references 2.1.0 versions of all the assemblies. If you update the packages to 2.1.1, those packages will win and you will stop using the shared framework. Essentially, you end up running with the 2.1.1 dlls deployed locally instead of running on the shared framework. Ideally, patches would be delivered via the SDK and runtime install only but we currently publish packages because of .NET Framework and other edge scenarios but it ends up causing this confusion.

@lmcarreiro
Copy link

Is there any advantage in using the Microsoft.AspNetCore.App metapackage instead of using the Microsoft.NETCore.App metapackage plus only the individual dependencies from Microsoft.AspNetCore.* that I really need?

If I use the Microsoft.AspNetCore.App, will I have all that more than 100 packages/DLLs loaded at runtime or just the ones that I really use? I think .NET Framework used to load every DLL inside the bin directory.

What is the recommended way (Microsoft.AspNetCore.App vs Microsoft.NETCore.App + individual dependencies) considering that I'm running inside a docker container?

@poke
Copy link
Contributor

poke commented Sep 6, 2018

If I use the Microsoft.AspNetCore.App, will I have all that more than 100 packages/DLLs loaded at runtime or just the ones that I really use?

The shared framework Microsoft.AspNetCore.App is distributed with the .NET Core runtime, so you are not actually publishing the packages that you are using. They are already there. But other than that, it will only use those packages that are actually used. That was a promise from the meta packages early on that they would strip unneeded dependencies during publish.

I think .NET Framework used to load every DLL inside the bin directory.

Not automatically, only if you actually have something that loads the assembly. But yeah, with the .NET Framework you would end up with a lot assemblies that you wouldn’t need since that assembly stripping is not available.

What is the recommended way considering that I'm running inside a docker container?

If you are using .NET Core, regardless of whether you run inside a container or not, you should just reference Microsoft.AspNetCore.App and use the Microsoft.NET.Sdk.Web project SDK. That’s basically what the templates will already give you by default. And it’s a good default :)

@MatthewLymer
Copy link

Is there any advantage in using the Microsoft.AspNetCore.App metapackage instead of using the Microsoft.NETCore.App metapackage plus only the individual dependencies from Microsoft.AspNetCore.* that I really need?

I might be wrong, but I think the advantage is a smaller deployment package as well as the ability to get bug fixes by updating the runtime instead of updating all the packages in your application.

In addition to getting fixes via a runtime update, you can be sure that all packages within the metapackage are compatible (and presumably thoroughly tested to work well together).

I'm with you on the thought process, include just what you need, which I thought was a main tenet for creating .NET Core in the first place.

@natemcmaster
Copy link
Contributor

I'm closing as this repository is about to be archived in favor of https://github.com/aspnet/AspNetCore. If you still have concerns or questions about Microsoft.AspNetCore.App, please open a new issue on the new repo.

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