Force Nuget package to use specific version of sub dependency? - c#

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.

Related

How do I control the version of sub-dependencies in a C# project?

Our organization has an internal NuGet package with a dependency on Microsoft.Extensions.Logging.Abstractions, minimum version of 3.1.10.
One of our developers updated another NuGet dependency to a >5.0 version. This NuGet dependency also had a dependency on Microsoft.Extensions.Logging.Abstraction. This update caused all dependecies of Microsoft.Extensions.Logging.Abstraction to be moved up to >5.0.
The erroneously updated nuget dependency was reverted, although the sub-dependency for Microsoft.Extensions.Logging.Abstraction has not reverted to its 3.1.xx version, which is causing build failures because were running on .NET core 3.1, and not 5.xx
Is there a way to get the sub dependency Microsoft.Extensions.Logging.Abstraction down to v 3.1.10?
Either something else has also changed or you're not running the restore from a clean state, as the version of Microsoft.Extensions.Logging.Abstractions would have gone back down again in the scenario you described.
There's a couple of ways to see where your problem is:
Longer more generally useful way
Delete your obj/ dir next to your project to make sure you're starting from a clean state, then run a dotnet restore.
Now open obj/project.assets.json. This lists all the packages in your dependency tree, together with the packages each one directly depends on.
Search for Microsoft.Extensions.Logging.Abstractions and check which version you've got. If it's still the higher version then you can see which package(s) are depending on it.
You can then trace the dependencies back until you end up at a package you reference directly, and you'll need to reference a lower version of that package.
Quick and easy way
Add a direct package reference to Microsoft.Extensions.Logging.Abstractions to your project at the version you want, then run dotnet restore. This will fail with package downgrade errors, and the error message will contain the dependency chain which is pulling in the higher version and causing the issue.

nuget not resolving dependency using what specified in nuget package for Microsoft.Extensions.Logging

Background:
I have created a class library for .net core (targetting v2.2), and I have a .net core application as well (targetting v2.2).
I am trying to export the library as nuget package and install it in my application.
Here is the dependencies for my library
I am able to export it as nuget package and for now I am storing it in local nuget repo.
But when I try to install this library package in my application it's not getting installed due to package version conflict for Microsoft.Extensions.Logging. Here's package manager console output.
Issue:
I have specified the exact version for Microsoft.Extensions.Logging i.e. [2.2.0] as we could confirm that in the screenshot showing dependency for my library, then why it's getting resolved to version 3.0.0?
How could I resolve this issue?
Details about the environment:
NuGet product used (Package Manager Console): Package Manager Console Host Version 5.3.1.6268
VS version (if appropriate): Microsoft Visual Studio Community 2019 Version 16.3.8
OS version (i.e. win10 v1607 (14393.321)): Windows 10 Enterprise Version: 1809
How could I resolve this issue?
To resolve the strange behavior in your side, you should clean the nuget cache before installing that package in your current project.
(To make sure the cache is cleaned up, I suggest you go %userprofile%\.nuget\packages to check if there exists Com.lib folder within the Packages folder)
I have specified the exact version for Microsoft.Extensions.Logging
i.e. [2.2.0] as we could confirm that in the screenshot showing
dependency for my library, then why it's getting resolved to version
3.0.0?
I think the one(Com.Mylib) you want to install is not the first one you pack. I mean that you may actually build and pack several different Com.Mylib package with different content. And all of their names is Com.lib.1.0.0.nupkg.
Nuget stores all nuget cache in %userprofile%\.nuget\packages. So if I once install one PackageA in any project. The cache of PackageA is stored there. And if I open a new project trying to install the PackageA with same version(1.0.0), it actually installs the one from cache. So we will meet this strange behavior:
Nuget can recognize the Com.lib package depends on other 2.2.0 packages. But when it tries to install that package, it finds the package has existed in cache. Then he tries to install the one from cache, and I guess content of the one in cache is different from your latest one, then the issue occurs.
Suggestions:
1.When developing locally, use project reference instead of Nuget packages.
2.If you need to test the nuget package every time after packing, please make sure the package version has increased.(1.0.0=>1.0.1=>1.0.3... or beta-1.0.12, preview-xxx)
3.If you have special reason do use same version 1.0.0, please clean the cache to avoid previous cache affects current project.
Hope all above helps :)

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.

Do I need to install Package Dependencies when using PackageReference

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.

Categories