Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate Microsoft.Extensions packages into their own Framework (and workload) #67487

Open
AraHaan opened this issue Apr 2, 2022 · 22 comments
Open

Comments

@AraHaan
Copy link
Member

AraHaan commented Apr 2, 2022

For starters, the Microsoft.Extensions.* packages that are from this repository are great, well known, and also well used (with a majority used by tons of packages that result in a huge dependency chain of just those packages alone if you count the transitive dependencies).

Because of this I would like to suggest making them into an framework named Microsoft.NETCore.Extensions.App framework that can be used for all types of apps, This framework would replace the nuget package versions and support .NET 6 at minimum (or rather the TFM that the packages all commonly support at minimum), also make them into an workload that can be installed into the .NET 7 SDK (not the .NET 6 one).

Other changes that would need to be made:

  • Migrate the usage of them in dotnet/aspnetcore (and possibly other repos) to the workload version (An Sdk change would need to be made to make it know about the new workload before then).
  • A nuget.org change would need to be made to make it possible to obsolete the Microsoft.Extensions nuget package for that workload so they get warned to "install the workload instead".

Pros of the change:

  • the libraries could benefit from crossgen2 for startup performance and various other things that might make them able to be optimized more than what the package version can offer.
  • more easier to use and less chance of a dependency version conflict (the updates would flow in when you update the workload and would update for all projects) (less chance of dll hell at runtime too).
  • overall the workload experience would be better than the package approach here for these well known packages that can become their own framework (because there are a lot of them that it would be more logical to make it a framework).
  • easier to contribute to projects depending on the workload as then it can be listed as an hard requirement to have the workload installed when you open their Visual Studio solution file.

Cons of the change:

  • Might not support as many TFMs as the package version (unless there is a way to preserve that one too).
  • Would require some help to configure the workload installer generation for this in this repository, however the workload would probably need it's own SDK to insert itself into KnownFrameworkReference and define a property responsible for enabling the insertion and framework reference.
@dotnet-issue-labeler
Copy link

I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label.

@dotnet-issue-labeler dotnet-issue-labeler bot added the untriaged New issue has not been triaged by the area owner label Apr 2, 2022
@teo-tsirpanis teo-tsirpanis added the packaging Related to packaging label Apr 2, 2022
@teo-tsirpanis
Copy link
Contributor

The packages in the Microsoft.Extensions family are plain-old general-purpose libraries. They need no special SDK support to warrant their own workload. And they also have to support .NET Framework through .NET Standard 2.0, so obsoleting the NuGet cannot happen.

@AraHaan
Copy link
Member Author

AraHaan commented Apr 2, 2022

Hmm I guess the framework option could work for .NET Standard based frameworks (like .NET Framework for example) right?

Or is FrameworkReference not possible for sdk style .NET Framework projects?
Although the users might not be using sdk style though 🤔.

I guess the deprecation message could be added to the .NET SDK when it sees them referencing the packages in .NET 6+ to use the workload instead.

@teo-tsirpanis
Copy link
Contributor

I still don't understand why to make them on their own shared framework. Extensions is a library, not an app model like ASP.NET Core, Windows Desktop or MAUI. Imagine needing a shared framework for Newtonsoft.Json.

@AraHaan
Copy link
Member Author

AraHaan commented Apr 2, 2022

Newtonsoft is a single package, Extensions is not (and is often considered by many it's own framework because of that).

@teo-tsirpanis
Copy link
Contributor

That is a miconception. Extensions is like the Windows Community Toolkit. A set of libraries that could have well resided in the BCL or in a third-party library. There's absolutely nothing special about them.

@AraHaan
Copy link
Member Author

AraHaan commented Apr 2, 2022

While that may be the case, take a look at the ASP.NET Core framework reference, almost (if not all of them) are included in it, however they could have been instead moved to their own framework that one would have to opt-into using (with asp.net core projects opting into it by default). Because of that many people thought it was a great idea to try to manually reference the ASP.NET Core framework when using:

  • WindowsDesktop
  • MAUI

However it would then result in failure to run the program due to that (because they want the extensions to be used from a framework and not from a package because their application is FDD and not self-contained) with it thinking that the relevant runtime is not installed (WindowsDesktop/MAUI).

That was one of the main reasons for filing the issue, along with the reasons I listed above like enabling crossgen2 on all the Microsoft.Extensions assemblies that are inside the reference to boost statup performance (which can also indirectly improve asp.net core / efcore as well).

And yes my argument is, if asp.net core apps can use them in FDD without needing the packages, so should any other type of project if they opt-in to not using the packages but still be able to use them the same way asp.net core apps can (also doing such could bring down the size of the asp.net core framework itself by at least 3~5 MB or so by having the source code to that framework also opt-in to it, it's planned to be a workload anyway so why cant workloads depend on other workloads?).

Also I forgot 1 other reason as well:

  • Imagine a security issue existed in an Microsoft.Extensions.* library, with the package being referenced. A typical developer might not be aware of said issue and might skip the update thinking that it might not affect their project, likewise if the project was already compiled with the package they will not get the patch to automatically be applied when they run the application.
    • This would not be an issue if the workload existed as it would be easy to let the developer know "hey update this workload to this security patch." and then when they run the FDD application it will use that patch (without being forced to update the package themselves, recompile, and pray the updated dll was copied).

@ghost
Copy link

ghost commented Apr 2, 2022

Tagging subscribers to this area: @dotnet/area-meta
See info in area-owners.md if you want to be subscribed.

Issue Details

For starters, the Microsoft.Extensions.* packages that are from this repository are great, well known, and also well used (with a majority used by tons of packages that result in a huge dependency chain of just those packages alone if you count the transitive dependencies).

Because of this I would like to suggest making them into an framework named Microsoft.NETCore.Extensions.App framework that can be used for all types of apps, This framework would replace the nuget package versions and support .NET 6 at minimum (or rather the TFM that the packages all commonly support at minimum), also make them into an workload that can be installed into the .NET 7 SDK (not the .NET 6 one).

Other changes that would need to be made:

  • Migrate the usage of them in dotnet/aspnetcore (and possibly other repos) to the workload version (An Sdk change would need to be made to make it know about the new workload before then).
  • A nuget.org change would need to be made to make it possible to obsolete the Microsoft.Extensions nuget package for that workload so they get warned to "install the workload instead".

Pros of the change:

  • the libraries could benefit from crossgen2 for startup performance and various other things that might make them able to be optimized more than what the package version can offer.
  • more easier to use and less chance of a dependency version conflict (the updates would flow in when you update the workload and would update for all projects) (less chance of dll hell at runtime too).
  • overall the workload experience would be better than the package approach here for these well known packages that can become their own framework (because there are a lot of them that it would be more logical to make it a framework).
  • easier to contribute to projects depending on the workload as then it can be listed as an hard requirement to have the workload installed when you open their Visual Studio solution file.

Cons of the change:

  • Might not support as many TFMs as the package version (unless there is a way to preserve that one too).
  • Would require some help to configure the workload installer generation for this in this repository, however the workload would probably need it's own SDK to insert itself into KnownFrameworkReference and define a property responsible for enabling the insertion and framework reference.
Author: AraHaan
Assignees: -
Labels:

area-Meta, packaging, untriaged

Milestone: -

@ericstj ericstj added area-Extensions-Primitives and removed area-Meta packaging Related to packaging labels Apr 14, 2022
@ghost
Copy link

ghost commented Apr 14, 2022

Tagging subscribers to this area: @dotnet/area-extensions-primitives
See info in area-owners.md if you want to be subscribed.

Issue Details

For starters, the Microsoft.Extensions.* packages that are from this repository are great, well known, and also well used (with a majority used by tons of packages that result in a huge dependency chain of just those packages alone if you count the transitive dependencies).

Because of this I would like to suggest making them into an framework named Microsoft.NETCore.Extensions.App framework that can be used for all types of apps, This framework would replace the nuget package versions and support .NET 6 at minimum (or rather the TFM that the packages all commonly support at minimum), also make them into an workload that can be installed into the .NET 7 SDK (not the .NET 6 one).

Other changes that would need to be made:

  • Migrate the usage of them in dotnet/aspnetcore (and possibly other repos) to the workload version (An Sdk change would need to be made to make it know about the new workload before then).
  • A nuget.org change would need to be made to make it possible to obsolete the Microsoft.Extensions nuget package for that workload so they get warned to "install the workload instead".

Pros of the change:

  • the libraries could benefit from crossgen2 for startup performance and various other things that might make them able to be optimized more than what the package version can offer.
  • more easier to use and less chance of a dependency version conflict (the updates would flow in when you update the workload and would update for all projects) (less chance of dll hell at runtime too).
  • overall the workload experience would be better than the package approach here for these well known packages that can become their own framework (because there are a lot of them that it would be more logical to make it a framework).
  • easier to contribute to projects depending on the workload as then it can be listed as an hard requirement to have the workload installed when you open their Visual Studio solution file.

Cons of the change:

  • Might not support as many TFMs as the package version (unless there is a way to preserve that one too).
  • Would require some help to configure the workload installer generation for this in this repository, however the workload would probably need it's own SDK to insert itself into KnownFrameworkReference and define a property responsible for enabling the insertion and framework reference.
Author: AraHaan
Assignees: -
Labels:

untriaged, area-Extensions-Primitives

Milestone: -

@ericstj
Copy link
Member

ericstj commented Apr 14, 2022

@eerhardt @davidfowl @maryamariyan -- thoughts on this? One thing we could consider is adding more extensions packages to the base shared framework rather than ASP.NETCore shared framework and keep the package/framework duality.

@eerhardt
Copy link
Member

I don't think we will get rid of the NuGet packages. We would need some pretty strong reasoning to justify removing the NuGet packages.

I agree with @ericstj above that if we think this justifies its own "shared framework", we should just move them into the Microsoft.NETCore.App shared framework. These libraries already exist in dotnet/runtime. There would be no real benefit to splitting them into their own shared framework.

But I don't think the above is strong enough justification for doing this work. If you use these libraries outside of ASP.NET, and you need fast startup, you can publish your app with PublishReadyToRun=true, and these assemblies will be pre-compiled. If you need to share them across multiple apps in order to save size, we should enable that scenario generically for any NuGet packages before solving it specially for Microsoft.Extensions. For example, the dotnet store command was built to do something like this. If reusing libraries in a common location is necessary, something like that will solve it for everybody - not just Microsoft.Extensions.

@AraHaan
Copy link
Member Author

AraHaan commented Apr 15, 2022

What I wanted was to have them in something like a framework where they would get serviced for all of my code at once so the serviced code gets run on all of them whenever the .NET SDK updates, a lot of people could agree with me on this one.

Placing it in the base shared framework would be a good option too. While the packages might be great (they get copied to the output directory which is not always the best option for everyone). After all not everyone keeps track of package updates and that can result in security problems in their app where placing them in a shared framework would eliminate that issue as then updating the shared framework when a servicing release is issued would be a far more better (and safer) option. This is why I am reluctant to use the packages as a lot of people do not wildcard them with *-* because sometimes if they do a prerelease build might be breaking for them.

Besides they get versioned with the rest of the projects in this repo so I think having both the package option and having them in the base shared framework would be the best option (which also exists for System.Text.Json and other libraries in the base shared framework).

While dotnet-store is an option, it would not be the best option for end users who might want to use the app (as some programs that might do this might be closed source so they would not have the source code to run the command). Besides End users really just want to install the runtime & try to run the app (however it would be nice if one can tell the apphost to instead link to the sdk instead of the runtime).

@eerhardt
Copy link
Member

eerhardt commented Apr 15, 2022

We can leave this issue open for a while to get feedback from others in the community if they see high value in doing this work. But without overwhelming feedback that putting the Microsoft.Extensions assemblies into the shared framework would benefit a lot of users, I don't think it is likely to get implemented.

After all not everyone keeps track of package updates and that can result in security problems in their app where placing them in a shared framework would eliminate that issue as then updating the shared framework when a servicing release is issued would be a far more better (and safer) option.

Again, the Microsoft.Extensions libraries are not special in this regard. A security issue could be found in any library. There are other mechanisms for finding security vulnerabilities in your dependencies. Here's one example: https://devblogs.microsoft.com/nuget/how-to-scan-nuget-packages-for-security-vulnerabilities/.

@davidfowl
Copy link
Member

I'm open to that discussion 😃

@AraHaan
Copy link
Member Author

AraHaan commented Apr 18, 2022

Another option could be to do something similar to how the WindowsDesktop shared framework has profiles and do an Extensions profile on the base shared framework that does not get used by default and for those who use that profile to gather the telemetry on (unless they opted out by environment variable). And then when more usage data is in merge the 2 profiles (when it is determined to be well used and not just on the aspnetcore repo and projects using ASP.NET Core).

@ericstj
Copy link
Member

ericstj commented Apr 19, 2022

Another option could be to do something similar to how the WindowsDesktop shared framework has profiles and do an Extensions profile

I'm not sure that really solves any problem, just another implementation option. The reason this was done in WindowsDesktop was to hide API and build tooling. I don't think we really care about hiding API here -- it's already segmented well by namespace.

IMO to justify work we don't need "options" here. We need a clear set of pros/cons that makes it a winning value proposition. Ideally that could be backed with data.

@maryamariyan maryamariyan removed the untriaged New issue has not been triaged by the area owner label Apr 19, 2022
@maryamariyan maryamariyan added this to the Future milestone Apr 19, 2022
@maryamariyan maryamariyan added the needs-author-action An issue or pull request that requires more info or actions from the author. label Apr 19, 2022
@ghost
Copy link

ghost commented Apr 19, 2022

This issue has been marked needs-author-action since it may be missing important information. Please refer to our contribution guidelines for tips on how to report issues effectively.

@AraHaan
Copy link
Member Author

AraHaan commented Apr 20, 2022

What I can think of so far:

Pros:

  • Projects can use the types and members from the Extensions assemblies without needing the packages.
  • Projects can get less files copied to their outputs when FDD.
  • Projects that normally do not maintain nuget dependencies would get free servicing updates when either Visual Studio or Windows Update patches their runtime major version (security and bug fixes that they would otherwise miss out on).
  • Less disc space wasted downloading the packages as they would be part of the base shared framework instead.
  • Less network usage (and faster restore) as the packages would become optional (unless they want to either roll back a breaking change or opt into the daily package builds that are not part of any daily sdk / runtime installer builds or not part of what the install scripts would install as it is too new)
  • Could simplify the Dependencies in the aspnetcore repository (and others) that use the package versions (they could use the ones in the base shared framework in .NET 7+). The change would mean that the ASP.NET Core framework assemblies list would get smaller, which means in turn that it's own runtime would also be smaller (because they would be moved to the base shared framework for the ones that exist in that framework reference that are package references to the ones in this repository) which in turn allows them to be used for any projects due to the fact they are generic enough where they can be used for any project.
  • Could resolve problems that the package version might have (example could be that an extensions package might have not been patched to remove the S.R.CS.U dependency and nobody noticed it until they installed the package because the S.R.CS.U dependency no longer gets updated packages released). AKA the framework reference might catch this and will immediately get patched to then not include the S.R.CS.U dependency at all.

Cons:

  • Would not handle fresh builds in the nuget feed which are not yet part of the daily feed builds that the install script/installers would install (forcing package to be used until then for some).
  • The Extensions packages that exist in the aspnetcore repository would not be possible to be included in the base shared framework (due to the fact it was made specifically for ASP.NET Core)

@ghost ghost added needs-further-triage Issue has been initially triaged, but needs deeper consideration or reconsideration and removed needs-author-action An issue or pull request that requires more info or actions from the author. labels Apr 20, 2022
@jkotas
Copy link
Member

jkotas commented Apr 20, 2022

Less disc space wasted downloading the packages as they would be part of the base shared framework instead.

It is not true if your project depends on netcoreapp shared framework only and does not use any of these packages. We do publish packages with netcoreapp shared framework only (https://dotnet.microsoft.com/en-us/download/dotnet/6.0).

@maryamariyan maryamariyan removed the needs-further-triage Issue has been initially triaged, but needs deeper consideration or reconsideration label Apr 26, 2022
@wtgodbe
Copy link
Member

wtgodbe commented Apr 18, 2023

If we do wind up moving these into Microsoft.Netcore.App it will require a reaction in aspnetcore, please keep me in the loop if we wind up taking that path.

@trylek
Copy link
Member

trylek commented Apr 18, 2023

We just hit this in our efforts on publishing Linux Docker containers using the combined ASP.NET + runtime Crossgen2 composite build, please see here:

In particular, we're hitting problems with the Microsoft.Extensions.Logging.Abstractions assembly because both aspnetcore and SDK reference it and they may end up picking up different versions of the assembly due to various latencies in the build.

@AraHaan
Copy link
Member Author

AraHaan commented Apr 19, 2023

Yep, that was another reason why I opened this issue as well, to discuss a way to and permanently resolve the problem via roll forward logic that already exists in the way the runtime works which I think could solve the aspnetcore and the SDK issue with it loading up wrong versions at the same time during build.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants