Nuget package dependency being treated as sub depedency looses version constraint - nuget

Let's say I create a new class library project. I add the Entity Framework 6.1 NuGet package to it, then create a new NuGet package from the class library project with nuget pack MyProject.csproj. I get a nice npkg with a depedency to Entity Framework 6.1.
Then, I decide to add a reference to the GraphDiff NuGet package which has a dependency to EntityFramework >= 6.0, the resulting class library npkg has only a dependency to GraphDiff and a note that it may have sub-dependencies, but nothing about it being Entity Framework and especially version 6.1.
Problems arise when I include the class library npkg into a project: Entity Framework 6.0 gets installed while it should have installed 6.1.
Is there a way around this?
I get this with NuGet.exe 2.8.50926.602

I found that I must use a nuspec file and manually specify a dependencies section, like so:
<?xml version="1.0" encoding="UTF-8"?>
<package>
<metadata>
**snip!!**
<dependencies>
<dependency id="EntityFramework" version="6.1.2" />
</dependencies>
</metadata>
</package>
I haven't been able to change anything working with the nuget project's packages.config file.
There's some valuable information about version dependency on Rick Strahl's web log

Related

Is there a way to control Nuget's over-eager references?

I'm just getting started with Nuget, and moving much of my team's intra-team and interdepartmental references into packages on a private nuget feed. The thing I'm observing though is that when my packages have their own dependencies, those secondary dependencies get added to my projects as references as though the projects are using them directly.
This works from a build & release perspective since the dependencies get packaged up correctly, but for larger projects the references list gets rather bloated compared to the assemblies actually referenced in code. In a hypothetical cleanup exercise, it seems like it would be difficult to determine which assemblies were this type of secondary dependency and which were simply no longer used.
Is this just an unfortunate consequence of Nuget works? Is there a different way to use Nuget that doesn't result in these noisy references?
For example: I have project MyProject, which uses assembly DependencyA directly. DependencyA references assembly LibraryX and as such LibraryX is required at runtime for MyProject, even though MyProject doesn't use it directly. For the sake of the example let's say LibraryX is distinct enough for it to be its own package.
In this scenario, prior to Nuget, the assemblies would live in source control, and could be packaged up during build/publish/deploy without needing an assembly reference in MSBuild. In this case MyProject has an MSBuild assembly reference to DependencyA, but not to LibraryX.
However, upon migrating to Nuget and consuming these dependencies via packages, the nuspec for DependencyA expresses a dependeny on LibraryX:
<package >
<metadata>
<id>DependencyA</id>
<version>1.0.0</version>
<authors>Initech</authors>
<owners>Initech</owners>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<license type="expression">MIT</license>
<description>A Dependency</description>
<tags>Dependency A</tags>
<dependencies>
<group targetFramework="net40" >
<dependency id="LibraryX" version="1.0.0" />
</group>
</dependencies>
</metadata>
</package>
When installing the DependencyA package on MyPrject, Nuget adds an MSBuild assembly reference for LibraryX to MyProject even though MyProject doesn't actually directly reference LibraryX.
You can control which assets are allowed to flow up the dependency chain using PrivateAssets, which I think is what you mean.
By default everything flows up though, so you can use packages you only depend on transitively in your code - in other words, the distinction between compile and runtime dependencies you mentioned in your comment doesn't exist by default.

Impossible to install GoogleAnalyticsTracker.Core Nuget package

I want to install the package GoogleAnalyticsTracker.Core from Nuget in my C++ project, but when I try to install, I get this error:
Could not install package 'GoogleAnalyticsTracker.Core 4.0.0'. You are trying to install this package into a project that targets 'native,Version=v0.0', but the package does not contain any assembly references or content files that are compatible with that framework. For more information, contact the package author.
I don't know why it cannot install it, my .NET Framework is v4.5.
This is the nuspec file:
<?xml version="1.0"?>
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata>
<id>GoogleAnalyticsTracker.Core</id>
<version>4.0.0</version>
<title>GoogleAnalyticsTracker.Core</title>
<authors>GoogleAnalyticsTracker</authors>
<owners>GoogleAnalyticsTracker</owners>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>GoogleAnalyticsTracker - A C# library for tracking Google Analytics.</description>
<copyright>Copyright © GoogleAnalyticsTracker 2012 - 2015</copyright>
</metadata>
</package>

How to properly define a NuGet package for an assembly where the dll file name is different from the assembly name?

I had to package a portable version of Newtonsoft.Json as an internal NuGet package under a different name (Newtonsoft.SL5.Json). The reason is that we are building into a shared bin directory and I do not want the Silverlight version to overwrite the full .NET version. (Yes, we still have Silverlight and yes the portable Json.Net version is not good enough for non Silverlight code we have)
The package file name is Newtonsoft.SL5.Json.8.0.1.19229.nupkg
Inside it there is Newtonsoft.SL5.Json.nuspec
Inside it there is lib\sl5\Newtonsoft.SL5.Json.dll
The nuspec file content is:
<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata>
<id>Newtonsoft.SL5.Json</id>
<version>8.0.1.19229</version>
<authors>Newtonsoft</authors>
<owners>Newtonsoft</owners>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>Json.NET Portable .NET 4.0</description>
<copyright>Copyright © James Newton-King 2008</copyright>
</metadata>
</package>
Now something I am doing wrong, because as a result, when adding the dependency in Visual Studio, the reference it produces is:
<Reference Include="Newtonsoft.SL5.Json, Version=8.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\..\packages\Newtonsoft.SL5.Json.8.0.1.19229\lib\sl5\Newtonsoft.SL5.Json.dll</HintPath>
<Private>True</Private>
</Reference>
And of course, there is no such assembly Newtonsoft.SL5.Json. It should be Newtonsoft.Json.
So, I am doing something wrong. How should I change the NuGet package so that it uses the correct assembly name, i.e. Newtonsoft.Json? Because even though I changed the file name, the assembly name is still the same.
while adding reference IDE takes .dll files that are included in the package (lib/{platform}/). If you rename those files added and packaged in nupkg file -> those should be added in element.

nuget pack ignores package.config dependencies

I cannot get nuget pack X.csproj to recognize package dependencies in a project. Amazingly, when packaging, the diagnostic message “Found packages.config. Using packages listed as dependencies” is printed, but in the end the <dependencies/> tag in the .nuspec file inside the package is empty.
The packages.config for the project does indeed contain references:
<packages>
<package id="SmartAction.Logger" version="1.0.2.0" targetFramework="net40" />
<package id="SmartAction.Pervasive" version="1.0.1.0" targetFramework="net40" />
</packages>
To narrow the problem down, I removed my own parallel .nuspec file, and mostly all switches from the nuget pack command:
> nuget pack libToneDetection.csproj -prop Configuration=Release
MSBuild auto-detection: using msbuild version '14.0' from 'C:\Program Files (x86)\MSBuild\14.0\bin'.
Attempting to build package from 'libToneDetection.csproj'.
Packing files from '[snip]\Core\ToneDetection\libToneDetection\bin\Release'.
Found packages.config. Using packages listed as dependencies
Successfully created package '[snip]\Core\ToneDetection\libToneDetection\SmartAction.Audio.ToneDetection.1.0.0.0.nupkg'.
NuGet Version: 3.3.0.212
The only difference I can spot with this project is that its name is different from package name (I am trying to maintain them in sync but this is older stuff I am repackaging).
I doubt I had ever seen this before. I am finding questions on SO from people trying to prevent references in packages.config from becoming dependencies of the package, but none from those trying, like me, to beat the reverse problem. Help!
Addendum. I copied the project out of the solution with other projects to a temporary directory and rebuilt the package from there. Now one of the two dependencies from packages.config was added to the package:
<dependencies>
<dependency id="SmartAction.Logger" version="1.0.2.0" />
</dependencies>
Thinking of the differences between the two, the SmartAction.Logger package depends on SmartAction.Pervasive. But the package I am compiling really uses both.
To me, either behavior looks incorrect. Am I hitting a nuget bug, or a cryptic complex feature?
Xref: Opened https://github.com/NuGet/Home/issues/1867

Why does Nuget package pick the wrong platform?

I have a nuget package http://www.nuget.org/packages/Tavis.UriTemplates/ that has the following nuspec file,
<?xml version="1.0"?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>Tavis.UriTemplates</id>
<version>0.4</version>
<authors>Darrel Miller</authors>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<title>URI Template resolution library</title>
<description>Implementation of RFC 6570</description>
<tags>http</tags>
<releaseNotes>Added PCL version</releaseNotes>
<projectUrl>https://github.com/tavis-software/UriTemplates</projectUrl>
</metadata>
<files>
<file src="Packages\temp\UriTemplates\lib\Net35\*.*" target="lib\Net35" />
<file src="Packages\temp\UriTemplates\lib\portable\*.*" target="lib\Portable-Net40+WinRT45+WP71+sl4" />
</files>
</package>
If I install this package in a project that is .net40 or .net45 it selects the .net 35 DLL. Anyone have any idea why it doesn't select the PCL library?
NuGet treats PCL assemblies as less compatible than assemblies that target a specific version of the .NET framework.
For your NuGet package you can either add a .NET 4.0 and a .NET 4.5 assembly or remove the .NET 3.5 assembly.
Looking at the NuGet source code, in the VersionUtility class, a PCL assembly's weighting will be halved compared to an assembly that references the full version of .NET.
// we divide by 2 to ensure Portable framework has less compatibility value than specific framework.
return GetCompatibilityBetweenPortableLibraryAndNonPortableLibrary(projectFrameworkName, packageTargetFrameworkName) / 2;
With your NuGet package, even though the PCL assembly's compatiblity is higher based on the value returned from the GetCompatibilityBetweenPortableLibraryAndNonPortableLibrary method, the division by two makes the .NET 3.5 assembly more compatible.