aspnet / MetaPackages

[Archived] NuGet meta packages. Project moved to https://github.com/aspnet/AspNetCore
Apache License 2.0
211 stars 109 forks source link

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

Closed DamianEdwards closed 5 years ago

DamianEdwards commented 6 years ago

Discussion issue for https://github.com/aspnet/Announcements/issues/287

yang-xiaodong commented 6 years ago

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 commented 6 years ago

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

davidfowl commented 6 years ago

You can always reference individual packages.

scottaddie commented 6 years ago

@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 commented 6 years ago

@scottaddie yes it's .NET Core only.

DamianEdwards commented 6 years ago

@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 commented 6 years ago

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

DamianEdwards commented 6 years ago

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

mungojam commented 6 years ago

@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 commented 6 years ago

@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 commented 6 years ago

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:

https://github.com/Azure/azure-functions-host/issues/992

DamianEdwards commented 6 years ago

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 commented 6 years ago

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 commented 6 years ago

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: https://github.com/aspnet/EntityFrameworkCore/issues/11920

shep1987 commented 6 years ago

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

rguerreiro commented 6 years ago

@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 commented 6 years ago

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 commented 6 years ago

@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 commented 6 years ago

@rguerreiro AFAICS; the RunAsService() extension method is there in ASP.NET 2.1: https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.hosting.windowsservices.webhostwindowsserviceextensions?view=aspnetcore-2.1 The necessary package seems to support .NET Core 2.1: https://www.nuget.org/packages/Microsoft.AspNetCore.Hosting.WindowsServices/

rguerreiro commented 6 years ago

@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 commented 6 years ago

@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 commented 6 years ago

@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 commented 6 years ago

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

rihei commented 6 years ago

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...

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...

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

rihei commented 6 years ago

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 commented 6 years ago

@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 commented 6 years ago

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?

2) 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?

3) 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.

4) 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 commented 6 years ago

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 commented 6 years ago

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 commented 6 years ago

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 commented 5 years ago

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 commented 5 years ago

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.