Closed dazinator closed 7 years ago
Q1
NuGet does not have any context to understand that this is an ASP.NET project. The only thing it's concerned with is the target framework.
I'm not sure what you're suggesting scales well though, as we're only talking about 1 package here. Any thoughts @emgarten
Q2 We have story about listing/displaying only compatible packages here: https://github.com/NuGet/Home/issues/4071 Upvote and follow to stay up-to-date on that work.
@dazinator any reason you can't use?
<dependencies>
<group targetFramework="netcoreapp1.0">
<dependency id="Foo" version="1.2.0" exclude="Build,Analyzers" />
</group>
<group targetFramework="netcoreapp2.0">
<dependency id="Foo" version="1.3.0" exclude="Build,Analyzers" />
<dependency id="Foo.Bar" version="1.3.0" exclude="Build,Analyzers" />
</group>
</dependencies>
NuGet uses the nearest compatible group, and ignores all other groups.
@emgarten - those groups target tfm's - but aspnetcore1.0 isnt a tfm (each version of aspnetcore can run on potentially multiple tfm's). So targetimg a tfm is not enough to target a particular aspnet core version. For example netcoreapp2.0 can can run netcoreapp1.1 packages, so a netcoreapp20 project can be running aspnet core 1.1 not 2. Or a net46 tfm can be running aspnet core 1.0 or 1.1 etc
@dazinator there would be an ordering problem here first off. When walking this package restore would need to know the capabilities from all packages, and that wouldn't be known until the end. Each time a package changed and the capabilities changed everything depending on them would need to be re-walked, which ends up being a very time consuming and difficult issue. The project framework used to pivot currently does not change during the walk.
Having capabilities like this would also make it difficult for restore to understand what the intent of the package is and fail when needed. Things might be working fine in a project because Foo is there, but after upgrading a seemingly unrelated package a capability could change that would make other packages work differently. And the primary issue there is that it would be hard to track down what caused it all.
Having different package ids, or different versions of the package with exact dependencies on the dependency packages seems needed here. It might help if you give more details on why this pivot is important, I understand the feature request from the examples you gave, but not the high level goals and the uses.
@nkolev92 - the search results / compatibility feature you linked - thank you, but its decribing compat based on TFM (nuget already has that nailed for the large part). This request is describing compat via new concept to further restrict results after TFM is applied
@dazinator Yeah that's clear. That issue is about "listing" package based on compatibility, whatever that might be. Currently NuGet does not do any project compatibility checks when presenting package search results.
@emgarten - ouch yes I can see that would be nasty. Well thanks for considering it and I appreciate your response. An example is that, in asp.net core 1, the way you set up logging and DI is different than asp.net core 2. My library wants to support both asp.net core 1 and 2. But it relies on a dependency (nuget package) to set up the logging. Because of precisely this issue, if my package is installed into an asp.net core 1 projec, I should include the logging dependency for asp.net core 1. If its installed into asp.net core 2 I should include the logging dependency for asp.net core 2.0. At the moment these are two seperate package id's, and I therefore have to create two seperate packages of my own. This problem is only going to get worse from release to release so I was trying to think of possibilities.
That does sound painful! At one point aspnetcore was a TFM which enabled this, but it was later simplified to use just netcoreapp. I would think to some extent that TFM would still be useful, you could check later in a props/targets file if the package was installed where it couldn't work and then fail.
Currently NuGet does not do any project compatibility checks when presenting package search results.
Ha.. ok yes that definately gets my vote then.. i thought it atleast filtered some results based on tfm's in the solution.
Ok thanks, well I'll close this for now, but keep me informed if you come up with any bright ideas around this in the future! :-)
Fyi another example of the problem can be seen via: https://github.com/aspnet/EntityFrameworkCore/issues/8498 The guidance there is for all dependencies to upgrade to referencing microsoft.extensions.dependencyinjection version 2 so that they will work in asp.net core 2 apps. But they cant do this without dropping support for asp.net core 1 apps. So dependencies that wish to be used by both aspnet core 1 and 2 will now have create 2 seperate packages. @davidfowl is that correct?
And an example of an impacted dependency: https://github.com/autofac/Autofac.Extensions.DependencyInjection/issues/24
I will outline the scenario and suggestion..
The Problem
I would like to maintain a single nuget package that can be installed into asp.net core projects consuming:-
asp.net core 1
asp.net core 1.1
asp.net core 2.0
I am mentioning asp.net core as a concrete example, but this suggested feature, generalises.
I say "consuming" rather than
targeting
, because these are not TFM's - they represent a corresponding release of asp.net core packages.I can already create a single nuget package that can be installed into all of these projects, by targeting my nuget package
to all of the TFMs that the asp.net core packages also target
.However I can't:
Pivot my package installation (dependencies etc) based on which version of asp.net core is being consumed by the target project. For example, if my package is installed into
asp.net core 1.0
project, I don't need to install a dependency, which is needed when installed into anasp.net core 1.1
project.Prevent my package from being listed and installed into projects that are not relevant / compatible. For example, a developer with a console application, not interested in asp.net core, will open the package manager and search for
Foo
. They might see my package listedFoo.AspNetCore
.With 1) the only way to pivot the installation currently, is to create seperate nuget packages:
This has the following problems:
Foo.AspNetCoreV11
package may work perfectly fine for asp.net core v2 as well - but it we want to remain consistent we would have to create aFoo.AspNetCoreV20
anyway.AspNetCoreV11
package - but there is no way to surface that action to them, unless the TFM has also changed..AspNetCoreV1
,.AspNetCoreV2
.Multiply this problem for all of the other platforms out there that are not formal TFM's but on which an ecosystem of nuget packages are published for - a few examples might be: every cms (dotnetnuke, drupal, etc etc), nancy, aspnet core etc)
Feature Suggestion
A capability would just be a string.
For example, declared inside the nuspec for the
microsoft,aspnetcore.mvc
1.0.0 package could be capabilities it will add to a project once installed:Inside my package that
Foo.AspNetCore
I can depend on this capability:I haven't given a great deal of thought around the best way to express these within the nuspec prepcisely, but the idea behind the feature is that when managing packages for a project,
Foo.AspNetCore
would not show up in search results anymore, unless theaspnetcore
capability that it applies to, was part of my solution (i.e I have added themicrosoft,aspnetcore.mvc
nuget package which adds that capability). This is analogous to howItem Templates
work in Visual Studio project system extensibility - i.e they only show up based on capabilities of the project.When checking to see if a nuget package is compatible, in addition to checking the TFM is compatible, if the nuspec depends on
capabilities
then a capability check will restrict compatibility further.The desire would also be to allow a nuget package author so scope dependencies of their nuget package - i.e
Foo.AspNetCore
based on present project capability - so for example:So when the above package is installed into an project with asp.net core 1 capability it carries
Foo version 1.2.0
but when installed into a project with asp.net core 2, it carriesFoo version 1.3.0
andFoo.Bar version 1.3.0
When managing packages for a project, the search results would show all legacy packages (i.e packages not making use of this capabilities feature in the nuspec file) as before. However for packages that make use of this feature and have declared "capabiltiies" that they depend on, in their nuspec - these packages would only show up in the search results when the project / solution has that capability present.