nuget.config ignores dependencies of dependencies (sub-dependencies) - visual-studio

I have a nuget.config for my project and have specified a repositoryPath. I also have specified the globalPackagesFolder.
<config>
<add key="globalPackagesFolder" value="c:\p" />
<add key="repositoryPath" value="c:\p" />
</config>
Now I want to install a third party package to my project. This package is located correctly at my specified path.
When I try to install another package, that has a dependency to System.Net.Http which has other sub-dependencies, nuget is not able to install this package, because the path is too long.
The direct dependecies are located in my specified repositoryPath from the nuget.config. The problem is, that sub-dependencies are not located at this path. A file search in this repositories resulted in no matches.
The only reason I specified a repositoryPath in nuget.config is that I wanted to move the sub-dependencies to another folder, because otherwise the path is too long and nuget can't install the package. This is not a problem for my co-workers.
How can I change this behavior?
If this is not possible, is there another solution to my problem?
A co-worker sugested to shorten my Windows login, but this is not a solution. I also can't shorten our Teamcity user login name.
The package I try to install is developed by my company. So if I have to change settings in the package, this is not a problem.
I tried with Visual Studio 2017 Pro and Enterprise with Nuget 4.6.0 and Visual Studio 2019 RC with Nuget 5.0.0.
Target Framework is .NET Core 2.1
When I add the package System.Net.Http to my project manualy and install the package, there is no problem, but i would rather don't do this, unless there is no other solution.
Edit:
To clarify the situation: If I install Package A that has a dependency to package B and B has a dependency to Package C, Package A is in my specified Path, but B and C are not. I don't even know, where Package B and C are located.

nuget.config ignores dependencies of dependencies (sub-dependencies)
This is the correct behavior for .NET Core project.
In dotnet core, or projects that use PackageReference, reference to only the immediate dependencies are listed and only download the immediate dependencies to the package cache.
That is the reason why you install Package A that has a dependency to package B and B has a dependency to Package C, Package A is show up in your project file like:
<PackageReference Include="PackageA" Version="1.0.0" />
and cache in your specified Path, but B and C are not.
This is a one of the biggest advantages of PackageReference where we don't clutter the project file with gazillion dependencies which the consumer probably doesn't care about. Install your nuget package to a project, navigate to the project_root/obj/project.assets.json and open this json, you'd see your package listed along with its dependencies. If you see your intended dependencies here, it validates that package is authored correctly. But NuGet will not restore the dependencies to the packages cache unless you install these dependencies directly.
Hope this helps.

Related

How do you test a nuget package?

I am producing a nuget package (some c# dlls that are then built into a nuget package and then uploaded to our nuget server)
I would like to have a way to test the package before I bother uploading it to a server.
I have a test project that has the package installed
Is there a way (in command line etc) to uninstall the release package from the project, and install a candidate package from the local machine in its place? (to test that the new package build is actually good?).
It would be good to have a one click update and restore of this candidate package too, so if I do a code change in my code thats being packaged, I can just have a one-click "build -> package candidate package -> restore candidate package on the test project".
In short: I change code in my package. click a button, then just hit F5 in the test project and it runs with the latest code changes.
AFAK, to realize this, you have to modify the PackageVersion node to make such nuget package unique every time.
Assume that your lib project and main project are all new-sdk projects.
1) Add such node under the csproj of the class library project and make the PackageVersion unique. Also check this link:
<PropertyGroup>
<PackageVersion>1.0.0-re-$([System.DateTime]::Now.ToString('yyyyMMddHHmm'))</PackageVersion>
</PropertyGroup>
2) change your main project's csproj file to this:
<ItemGroup>
<PackageReference Include="Lib" Version="1.0.0-*" />
</ItemGroup>
It will use the latest version of the nuget under the nuget package source.
3) if you modify the lib project and then finish it, please right-click on the lib project Properties-->Pack to generate the new version.
4) then build the main project first, and then you can use the latest changed nuget package's code on the main project.
And if you want to restore to use the previous version of the nuget package, there is no way but you only have to install that version manually under Nuget Package Management.

NuGet Framework package with dependencies from Core project

I am trying to reference from a .NET Core 3.1 project, a NuGet package that targets only net40 via the NuGet compatibility shim. The package is added to my project, however the net40 dependencies are not.
The package is structured as:
lib\
net40\
AssemblyA.dll
nuspec:
<dependencies>
<group targetFramework="net40">
<dependency id="PackageB" version="1.0" />
</group>
</dependencies>
Visual Studio's Package Manager lists the dependencies, but when installed, the dependencies are not listed by VS' Preview Changes window and are indeed not installed. PackageB also targets net40.
It does work if I:
Include the dependencies in an "Any" (blank) dependency group as well as under net40
Remove the net40 dependency group and list the package directly under <dependencies> as a flat list
Remove the net40 under lib\ and use a flat list
These are not ideal as it obfuscates the true nature of the targets frameworks. The last two produce NU5128 on pack. For future reference, I should mention that it's required to remove the dependencies from the local cache for even these scenarios to work (surely a bug?).
Any ideas on how to pull dependencies from such packages? Is this simply not supported? A good test example of this is the "Polly.Net40Async" package.
(VS: 16.6.5, dotnet: 3.1.302, PackageReference, Windows 10)
I am trying to reference from a .NET Core 3.1 project, a NuGet package
that targets only net40 via the NuGet compatibility shim. The package
is added to my project, however the net40 dependencies are not.
The nuget package only targets to net40 which means the package is used for net framework 4+.
And by default, Net Core projects cannot use this type of nuget unless the package and dependencies are listed as supporting Net Core or Net Standard.
==========================================
Also, you can notice the info from the Polly.Net40Async nuget package:
group targetFramework="net40" means that if your project targetframework version is 4+, it will install the listed dependencies.
So you should not install this type of packages into Net Core 3.1 project. And it is designed by the author.
Besides, if you change the sub folder of lib in the nuget package to any, you can add the dependencies into the Net Core project.
After all, any means it targets to any framework versions--net core, net standard, net framework. And you just need to remove the condition of the dependency (contention on Net Framework 4+).
====================================
Add more detailed info
Update 1
Actually, Net Core projects can install some nuget packages which only targets to Net Framework.
In my side, the package can be installed in the Net Core project.However, there is a warning which shows it may not be fully compatible with your Net Core project. Although you can use it, there are still some problems just not encountered in special situations.
For the dependencies, since your project targets to Net Core rather than Net Framework, the dependencies will not be installed automatically along with the main package. But you can manually install these dependencies separately through Nuget Package Manager UI.(search them and then install them one by one).
And if condition group targetFramework="net40" is met, it will install these dependencies automatically along with the main nuget package. But since your project targets to Net Core, it will not install them automatically.
As a suggestion, you could search these dependencies on the Nuget Package Manager UI, and then manually install them separately.

Nuget Packager task - dependency is not added

I'm using Visual Studio Team Services to automate the creation of a nuget package. This package has a dependency on another nuget package (Newtonsoft.Json v8.0.3). I have configured a Nuget Packager task as part of the build:
But the generated package doesn't contain the reference to the nuget package:
Running the following script on my local machine to generate the package:
nuget pack myproject.csproj -Symbols -IncludeReferencedProjects -Properties Configuration=Release -OutputDirectory bin/Release
I can see that the dependency is added to the generated package:
What am I missing here? Why the dependencies are not being added to to package that is being generated on the build server?
"IncludeReferencedProjects" is used to add the referenced project to the nuget package, not the referenced nuget packages.
Include referenced projects either as dependencies or as part of the
package. If a referenced project has a corresponding nuspec file that
has the same name as the project, then that referenced project is
added as a dependency. Otherwise, the referenced project is added as
part of the package. Learn more at NuGet.org.
When you create the nuget package for the project which referenced to another nuget package. The nuget package dependency will be added automatically if the nupkg file exists in the packages folder. For your issue, you can add a "NuGet Installer" task in your build definition to restore the nuget package files for your solution. And then when you create the nuget package for your project, the referenced nuget package will be added as dependency.
I have found a solution for my problem, even though I don't understand why the package was not being created properly.
So basically I have 2 builds:
a "generic" build that will compile the entire solution and run unit tests, etc (automatic, triggered on commit)
a build to generate the nuget package (manual)
This problem is on the 2nd build. I was trying to understand what were the differences between creating the package manually on my local machine and creating the package on the build server and I realized that on the build server I was not getting the source code for the solution, only for the project folder and the .nuget folder. Given that I have more than 40 projects in the solution it makes no sense to get the whole source code for the 2nd build, right? But for some reason this is not enough to generate the nuget package properly.
So, the solution to my problem was to get the source code for the following files/folders:
Project folder
.nuget folder (needed when restoring/installing the missing packages)
Solution file (mysolution.sln)

Configuring NuGet dependencies and VS2013

I wish to set up my NuGet dependencies such that:
Anyone checking out the project (i.e. other developers) will get the correct dependencies.
Anyone using my package will get the correct dependencies.
In VS2013 my NuGet dependencies are specified in packages.config
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="log4net" version="2.0.3" targetFramework="net45" />
</packages>
I noticed that you can also specify dependencies in the .nuspec file (much like a maven pom file) but this doesn't seem to be used by the package manager plugin.
<dependencies>
<dependency id="log4net" version="2.0.3"/>
</dependencies>
What is the correct way to configure dependencies and why?
The packages.config file lists all the packages that are currently installed for a given project. This includes any dependencies. NuGet will automatically update this file any time you add, update, or remove packages from your project, either through the NuGet UI or Package Manager Console (e.g. Install-Package log4net).
NuGet will automatically install any dependencies for a given package. NuGet will also follow the dependency chain for each of these other packages, until all dependent packages are installed. It will add these packages to the packages.config file to show that they have been installed. So you may initially install one package, but 10 packages may end up being installed based on all the dependencies. Again, this will be reflected in the packages.config file, which you shouldn't touch.
You do NOT need to edit this file.
The only way you should update packages.config is by installing or updating packages via the NuGet UI or Package Manager Console. Do not edit this file by hand.
EDIT: Add section about package restore
The packages.config file is also used by NuGet to restore packages (Automatic Package Restore) that do not exist on the user's hard drive. This is useful since you do not have to commit the packages folder to source control. So when another developer checks out your project, NuGet will automatically download any packages listed in packages.config before building. NOTE: This is not the same as installing packages. It is assumed that you've already used NuGet to install the package, which will update project references, add files, modify .config files, etc. Those changes should already be committed. All package restore does is download the binaries as if they were also committed, without bloating your repository. Package restore is mainly used for other developers building your project from source code. It is not applicable for installing a package you create, which is what the .nuspec file is for.
The .nuspec file is used when you are creating your OWN packages for others to use. The <dependencies/> section lists the packages YOUR package needs. When a developer installs YOUR package, NuGet will automatically install any dependencies listed in your .nuspec. Just like above, NuGet will follow the dependency chain by looking at each packages .nuspec file to see what dependencies it requires.
So unless you're CREATING a package, you do not have to worry about .nuspec files.
As you can see, NuGet uses the .nuspec file in each package to determine if there are any dependencies. Installing a package will update the packages.config files.
TL;DR: packages.config and .nuspec files are different things although somewhat related.

Should NuGet Spec detect dependencies?

I've just run nuget spec in the folder where my .csproj file is and it didn't write the dependencies to the .nuspec file. Should it have?
The solution has package restore enabled and builds fine on TeamCity.
Running nuget spec does not automatically include dependencies to other NuGet packages in your project. However, running nuget pack MyProject.csproj when you also have a nuspec-file will result in a nupkg-file where NuGet packages used in MyProject are included as dependencies in your package.
It is also worth noting that as of v2.5 (which is planned to be released some time at the end of April I believe), you'll also have the option to additionally include dependencies to other projects in your solution that also have nuspec-files:
When building a package from a project, when
-IncludeReferencedProjects is specified, projects referenced by the project are either added as a dependency of the package, if nuspec
file exists, or are added into the package if nuspec file doesn't
exist.
See changelog.txt for v2.5 for details.

Resources