-
Notifications
You must be signed in to change notification settings - Fork 258
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
Transitive Dependencies are referenced #6614
Comments
bump? |
This is a known design flaw of packages.config, and unfortunately there's not much you can do. For that reason, we've spent the last few years developing PackageReference Consider trying that out and give us any feedback. |
It appears to me that this is package authoring problem, not a restore problem. The package author should be able to declare what dependencies are private or not (since he knows) and the package consumer able to override these. |
I don't think I follow here. What's the difference between a public and a private dependency? NuGet doesn't really have that concept once the nupkg is built. |
Hi, In a nutshell, public dependencies are exposed through public API, private dependencies are not. e.g.:
As a Package author, I know (or should know) which of my dependencies are public (exposed to my clients) and which are private (only used internally), and should be able to say that in my nuspec. Public dependencies should be referenced, by the consumer of my package and Private should not. As it stands now, I can have a UtilityPackage that needs Newtonsoft, and people adding me as a NuGet package could call Newtonsoft arbitrarily even though they themselves have no dependency on them, which could break things if let's say tomorrow I decide to remove Newtonsoft dependency from my package. If, for whatever reason, the consumer wants to override the default package dependency, by all means. If you want a sample project demonstrating the difference, I can cook one up too! Thanks |
NuGet does not have a concept of public/private dependencies. When you have a project, you can decide whether the dependencies of your project are build time or runtime by playing with the metadata of the package declaration. developmentDependency=true in packages.config If you're using a library, there's no way to prevent the consumer from being able to code against it. That's just an extra API, same as yours. The access level is defined by the author the dll you're using. The example you're articulating is a user-error. |
Hey, Thanks for getting back to me. I understand that if my project A requires a package B, I can say whether my package B is a build-time or run-time dependency, so that if its build-time, it's excluded from the output. The problem is that the concept of public v. private is missing, so if I have a reference on a package A that depends (at runtime) on package B, not only do I get package B (as expected) but I also have a reference to package B, not as expected. Since I have a reference to Package B, it pollutes my access, and worse I can mistakenly call package B code directly. Here's a concrete example of the problem: I have a project that consumes as a NuGet package NuGet.Build.Tasks
This project compiles and runs fine. That's my point, if DependencyGraphSpec didn't expose Newtonsoft in its public interface (hence making it a public dependency, not a private one), and so people consuming NuGet.ProjectModel wouldn't need to reference Newtonsoft, despite depending on it at runtime. If, let's say tomorrow you switch to SimpleJson, it wouldn't be seamless, as there could be compile-time errors if the clients use JObject. If I author a package that depends on Newtonsoft but never expose Newtonsoft in my API, I can be free to mark it as a Private Dependency and people consuming my package dont need to have a reference to my package. |
I get your example. It's definitely not something that NuGet standalone can provide. |
Hello, If you are in the old project format, .NET Framework (old .csproj) and earlier, you have to add the reference to a transitive public reference manually. This means the default (and only) behaviour for .NET framework is to treat all dependencies as private (no transitive dependency). e.g.:
On the other hand, e.g.:
What I think would be the solution is something like:
So, in a nutshell, it is possible to do in .NET. Right now, PrivateAssets is always none on NuGet dependencies, so that could be the default. It's possible I'm misunderstading something, but I think this is essentially either a feature request, or a bug, since the default MsBuild behaviour for .NET framework is the opposite of NuGet. (bug?) |
PrivateAssets is used for dependency flow. If you have a package that's marked with private assets it merely prevents it from flowing to parent project or getting packed. For example, I'm developing
and the dependencies for the project are:
then when you pack that package, in the dependencies section you will only see package A. as per #5455. So for NuGet, when it gets the package CoolPackage, it only knows about packageA as a dependency, has no clue about package B. I'm not sure I understand what you're suggesting with the packages.config and old csproj scenario. |
Hello, My point is that it should, since currently this breaks encapsulation. A package author should be able to declare a dependency as private or not (just like we can declare a PackageReference or a ProjectReference we can say that they're private). My request is simple: Add an option at the .nuspec level (package authoring) to say that a dependence should not be transitively referenced.
My example simply shows that it is possible with .NET, hence
I showed this is doable in both the old and the new project format. Thanks |
Although like in your case:
This will be converted to below code in nuspec file:
So here exclude=all on MyPrivateDependency means, nothing will be flown from this to destination project, which is what you want isn't it? |
Hello, Sorry for the delay, I was under the weather. I thought e.g.: Consumer -> DirectDependency -> MyPrivateDepenency This is what the .nuspec looks like:
Tested it in the new and old .csproj format successfully! This is what project.lock.json results in:
Also, FYI I tested and discovered that PrivateAssets doesn't work for some reason for .NET standard. The private dependency does get copied to the output directory, but at runtime it fails to find it., giving a FileNotFound with the dll info. I guess the Doc could use some updating? Thank you for your time, I guess I'll go poke MicroSoft about this other problem next Gab |
Can you provide more details here or a sample repro case to depict what you're really seeing? And I agree doc should be updated to reflect the meaning of all these flags. I'll take a pass at it and update it accordingly. |
Sorry, I wasn't super clear. Not NuGet end, I think the behaviour using exlude="build" is exactly what I expected, since it is a runtime-only dependency (so no need to reference). Thanks, |
NuGet product used:
NuGet version: 4.5.1
VS version: 2015 update 3
Transitive dependencies are added as direct references to the consuming project.
There's no way of distinguishing private vs. public dependencies that I could find anywhere.
A public dependency is a dependency that the dependent will also need to reference (current default behaviour)
Described in this and this.
(private vs public)
Adding them directly to your package and using <reference> on only your lib (which is obviously a bad idea) still doesn't work, because MSBuild only copies dlls that are references.
Which is this issue, also a problem, since if the dlls are not copied you have to either copy them yourself through some MSBuild hack, a post-build hack, or as the first recommended work-around removing <references> hence defeating the purpose of using it in the first place.
The text was updated successfully, but these errors were encountered: