Do I need to install Package Dependencies when using PackageReference - c#

So I used to use the old packages.config method of installing nugets which worked by installing any dependencies when installing a package: i.e.
Package 1
Dependency 1
Dependency 2
I have now changed to use PackageReference but noticed as I was installing "Package 1" it would not automatically install the dependencies. As I wasn't sure I went and installed "Depdendency 1" and "Dependency 2" manually
Do I need to manually install "Depndendency 1" and "Dependency 2" when using PackageReference?

The direct answer to your question is simply no, you should not need to manually install the dependencies.
There have been a few changes and performance improvements in the recent VS 2017 and MSBuild work. There's some good information on what this means here:
In the past, if your project referenced package A, which in-turn referenced packages B, C and D, you would see all of them listed as your dependencies. With Transitive Package Restore, NuGet dynamically resolves dependencies giving you an uncluttered view of the packages you care about.
That explains the "missing" package references. If you're interested in the "missing" files themselves, there's more information on that too:
Solution-local packages folders are no longer used – Packages are now resolved against the user’s cache at %userdata%.nuget, rather than a solution specific packages folder. This makes PackageReference perform faster and consume less disk space by using a shared folder of packages on your workstation.
The reason I said should not need to is that there is a known issue around this area when mixing .NET Standard and .NET Framework.

Related

Force Nuget package to use specific version of sub dependency?

When installing the two Nuget packages Hl7.Fhir.DSTU2 and Hl7.Fhir.R4, we get something like this:
The package DSTU2 seems to have issues using Hl7.Fhir.Support.Poco version 3.4.0.
If we install DSTU2 on it's own, all packages are using the version 1.9.0.
Is there a way in the .csproj file to specify sub dependencies versions and have the .dll installed in specific folders?
Here are the 3.4.0 versions .dll in my debug folder
Yes, you just add a PackageReference in your project for the transitive dependency as well. NuGet picks a single version to use for each package you depend on, and if you have a direct reference to a package then NuGet will always pick this version due to its nearest wins rule.
As you've spotted though, this can't be a lower version than any of your dependencies require themselves, or you get a package downgrade error. This is intentional - if you reference packageA which says it needs at least a particular version of packageB, then given that you can only use one version of each package it stands to reason that you need at least that version of packageB.

How to handle NuGet dependency version resolution for the whole solution

I'm looking for a simple way to manage NuGet packages for the whole solution, to prevent conflicts between transitive NuGet packages when assembling all files into one installer.
When building a project all direct and indirect dependencies are analyzed and the NuGet resolution picks up the best matching version for each NuGet that is at least the same version as the lowest version and might also create binding redirects if necessary. (all good and fine)
The problem we have lately encountered was when we build the whole solution (200+ projects) at once, the resulting NuGet versions between all top level projects might not be identical. And due to the fact, that all resulting DLL and EXE files are installed into the same program files folder, the application can and will crash at runtime due to version mismatches when loading assemblies.
To better understand this issue I've created this sample repo.
The dependency graph looks like this:
Library1
Microsoft.IdentityModel.Tokens-5.2.1
Executable1
System.IdentityModel.Tokens.Jwt-5.3.0 (transitive reference: Microsoft.IdentityModel.Tokens-5.3.0)
Library1
results in: Microsoft.IdentityModel.Tokens-5.3.0
Executable2
Microsoft.IdentityModel.Tokens-5.2.1
results in: Microsoft.IdentityModel.Tokens-5.2.1
To demonstrate the problem, all projects compile to the same bin folder. When the whole solution is compiled and Executable2 is started, the application crashes, since the application expects Microsoft.IdentityModel.Tokens in version 5.2.1 but the actual version is 5.3.0.
For this constructed sample it is easy to find the problem and fix it with updating the Microsoft.IdentityModel.Tokens NuGet to the same version. (Manually, since Visual Studio Package Manager does not recognize this conflict in the consolidate tab).
But at a much greater scale it is far more complex to find those mismatches.
What we have found so far
Centrally managing NuGet package versions
Since it is not yet available, it cannot be used to solve the issue here.
Microsoft.Build.CentralPackageVersions
Unfortunately there is no IDE support for it, which makes managing NuGet packages very uncomfortable, which I would like to avoid if possible.
So my question is what is the best approach to avoid NuGet version conflicts between projects within the same solution?
We've experienced the same problem with some of our projects. We've been using Paket package manager since a couple of years and this has resolved that issue for us.
In short: you define on your solution level which packages you want to use in a file called 'paket.dependencies'. You can be very specific about versions, or let packet use the latest greatest. Then you can specify per project which NuGet package you want to use within that project in a 'paket.references' file. As the name implies, you reference to a package in the paket.dependencies file.
This will make sure, all references packages in your project will use the same package version. I hope this suits your needs as well.

Nuget Pack not including new files

I've added new models and helpers to my project, but when I run nuget pack and install the package in my project I don't see the new items in the Assembly Explorer nor can I use them. Am I missing something during the build that wouldn't include new files added to the package?
I'm using visual studio 2017 and the nuget cli
At a guess, you didn't change the package version when you changed the code and packed again. NuGet is designed such that the package id/version produces an immutable package. This means it's valid to download a package, say Newtonsoft.Json 12.0.1 from nuget.org just once, and every time you use that package in any project on the same computer you can re-use the same download, rather than having to download it every time you restore/build the project.
This causes some people problems when they're trying to test their packages. One option is to take advantage of Semantic Versioning and use 1.0.1-preview.1, 1.0.1-preview.2, so every single build of the project has a unique version number. In addition, or instead, you could use a nuget.config to set the globalPackagesFolder to a different location that gets cleared every time you change the package. If you delete the "cache", it can't reuse the old contents. But this only works if you control the machines that use the package. Once you publish the package where anyone else can use the package, you will cause problems if you change the contents, which is why nuget.org doesn't allow deleting packages, only unlisting them.
However, another possible solution is to just not use packages and simply use project references. Some people have the misconception that if you have two packages, one depends on the other, that they need to use package references to make sure NuGet dependency information flows. That's not correct. If you pack with the MSBuild pack targets (highly recommended, and the default option for SDK style projects), NuGet will always convert project references into NuGet dependencies. nuget pack will convert project references into dependencies when the other project also has its own nuspec file. When you test your project with project references, you never have to worry about immutable packages. Just pack when it's ready, but it's not needed for testing.
Maybe you have a .nuspec file (at the same level than your .csproj) that you need to edit to include new files?

Is NuGet metapackage reserved to .net core only?

In the .NET doc, I see a lot of explanations around nuget metapackages, bu all the samples are with .NET Core. Is it possible to create metapackage for full .net framework assemblies and consume this with a .net framework app?
Will it be possible only with ProjectReference and not with packages.config?
Thanks!
A metapackage is just a package that doesn't contain any content/libraries of its own and has dependencies to all the other packages that it encompasses. This isn't something specific to NuGet, by the way, many package managers have the same concept and usually call them meta packages too.
About NuGet specifically, since NuGet has to deal with different target frameworks and asset selection, which many package managers don't have to worry about, it might be necessary to put some fake information in the nupkg to make it work properly. What I think I've seen before is to create an empty file named _._ in the lib\target framework folders that match the TFMs that the dependant packages use. For example, if you create a metapackage for packages that have libs for net45 and netstandard2.0, then you'd have two files in the nupkg, lib/net45/_._ and lib/netstandard2.0/_._, both are empty. However, I haven't tested this myself, so you should, but just in case a nupkg with only a nuspec and nothing else doesn't work, try this.
Since meta packages aren't otherwise special (they have the same package type as "regular" packages), they work just fine with both packages.config and PackageReference. Meta packages are perhaps most useful for PackageReference, because it supports transitive dependencies. In other words, the user adds the metapackage, their csproj gets one reference and is otherwise "clean". With packages.config, when they add the metapackage, all of the transitive dependencies will also get added to packages.config and csproj.

Nuget Package without Package.Config?

I encountered a solution (.Net Full framework) Where there are no package.config in the solution and Feeds coming from In house Nuget servers.
Where list of packages are maintained, if not in Package.Config?
Where is the list of packages are maintained, if not in Package.Config?
First, you should make sure you have that solution have already installed the nuget package, once you install a package, NuGet will add Package.Config file to your project to record the dependency in either your project file or a packages.config file.
If you confirm that your solution has a nuget package installed, but there is no Package.Config file, your nuget package should use another management method: PackageReference
Edit your project, you will find following PackageReference list:
<ItemGroup>
<PackageReference Include="Contoso.Utility.UsefulStuff" Version="3.6.0" />
</ItemGroup>
See NuGet is now fully integrated into MSBuild for more details:
In the past, NuGet packages were managed in two different ways -
packages.config and project.json - each with their own sets of
advantages and limitations. With Visual Studio 2017 and .NET Core, we
have improved the NuGet package management experience by introducing
the PackageReference feature in MSBuild. PackageReference brings new
and improved capabilities such as deep MSBuild integration, improved
performance for everyday tasks such as install and restore,
multi-targeting and more.
The packages.config file could be somewhere else? In that case look in your msbuild project file (i.e. *.csproj, *.vbproj, *.vcxproj) and see where the references to that nuget assembly are coming from. Then look in that directory for the packages.config file. It might be more complicated than that, in which case, it's useful to do a global search for packages.config in your repo, to see where they reside (If they do exist at all).
This is a common practice: To have one project specify the nuget package, and all the other projects borrow it. As Jon said, this is really dependent on how the folks at your company and department set up your builds and dependencies.

Categories