class library with multiple nuget packages issue - nuget

I have a class library with numerous projects, each referencing each other, written in C#. This is a common library that I share with other projects. I have recently changed the mechanism that the library is shared to be via nuget. So for each project within the library, I have a post build event to create a nuget package eg.
"$(SolutionDir)\NuGet.exe" pack "$(ProjectPath)" -o "$(SolutionDir)\Packages"
This works nicely. It pushes the package to a shared folder in the file structure and the consuming project installs it from there. All projects packages are pushed to this folder.
I have ran in to a problem though. Lets say my library creates package X and Y. X has a reference to Y in the class library. In the consuming application, I need to use X, when I install it, it doesnt install the ddl from Y. I also need to install package Y. How can I set it up when package X is created, it also includes the necessary dlls's from package Y, without having to explicitly install it?

in the nuspec file of package X you can specify package Y as dependency
<dependencies>
<dependency id="Y" version="1.0" />
</dependencies>
More options around dependency can be found here http://docs.nuget.org/docs/reference/nuspec-reference#Specifying_Dependencies
For specifying files you could use
<files>
<file src="bin\Debug*.dll" target="lib" />
<file src="bin\Debug*.pdb" target="lib" />
</files>
More details here http://docs.nuget.org/docs/reference/nuspec-reference#Specifying_Files_to_Include_in_the_Package

Related

Custom NuGet package not installing in wix project

I generate a NuGet that is is just a number of redist files that I want to use in one of my projects. If I install it in a C# or C++ projects, it works. But when I try to install it in a wixproj project and I get the following message:
Could not install package 'package-1.0.0'. You are trying to install this package into a project that targets 'Unsupported,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 generate the package through a TeamCity task (using NuGet 5.6.0). When trying to generate the package with a NuGet CLI 5.8.1, I get the following warning:
*WARNING: NU5128: Some target frameworks declared in the dependencies group of the nuspec and the lib/ref folder do not have exact matches in the other location. Consult the list of actions below:
Add a dependency group for native0.0 to the nuspec*
Looked at https://learn.microsoft.com/en-us/nuget/reference/errors-and-warnings/nu5128, one of the solutions was trying a dependencies group targetFramework, (I used "native0.0") with no success. My nuspec is as follows:
<?xml version="1.0"?>
<package>
<metadata>
<id>package</id>
<version>1.0.0</version>
<authors>package</authors>
<owners>owner</owners>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>my package</description>
<copyright>© 2021 company, Inc</copyright>
<tags>native</tags>
</metadata>
<files>
<file src="downloads\Folder\win32.vs2017\file1.lib" target="lib\native\lib\win32.vs2017\" />
<file src="downloads\Folder\win32.vs2017\file1-debug.lib" target="lib\native\lib\win32.vs2017\" />
<file src="downloads\Folder\Include\**" target="lib\native\include\" />
<file src="build\package.props" target="build\native" />
</files>
</package>
And my props file
<Project>
<PropertyGroup>
<MyVersion>1.0.0</MyVersion>
</PropertyGroup>
</Project>
I can install other NuGet packages into wixprojects, so how I configure mine to work? Thanks.
OK I found it, the issue lies at the line
<file src="build\package.props" target="build\native" />
changing target to "build\" allows the NuGet to be loaded to any project type, included WixProj. Note that the NU5128 warning still exists though, but not an issue for me.

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.

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

using nuget.exe commandline to install dependency

I want to use nuget.exe (version 2.5) in my CI build pipeline to install a package which has dependency to another package.
I have following nuspec file.
<?xml version="1.0"?>
<package>
<metadata>
<id>A</id>
<dependencies>
<dependency id="B" version="1.0.0.1" />
</dependencies>
</metadata>
<files>
<file src="A.dll" target="lib" />
</files>
</package>
and similar for B.
and my packages.config file which I used to install is:
<packages>
<package id="A" version="1.0.0.1" allowedVersions="[1,2)"/>
</packages>
and I run following command:
NuGet.exe install packages.config -ExcludeVersion -Outputdir libs -source http://get.nuget.mydomain
I get output:
Successfully installed 'A 1.0.0.1'.
but do not get my dependency B installed.
But if put B separately in packages.config file, I get both A and B getting installed. I expected B to be installed when we install A as it is a dependency of A.
We do not put dlls in GAC (so I believe dependency resolution should not be a problem).Also I have opened A.nupkg and checked that is has dependency listed there.
Also when I install A from with in visual studio editor B also gets installed.(which is what should happen).
How do I use nuget.exe and install dependency B when i install A only (put A only in packages.config).
thanks
This is not possible. The behavior of the packages.config file is by design. Only things specified in the packages.config are installed, not their dependencies. All dependencies must be explicitly specified as well.
If you look at the source code you will see that nuget.exe install packages.config (http://nuget.codeplex.com/SourceControl/latest#src/CommandLine/Commands/InstallCommand.cs) uses PackageExtractor.InstallPackage (http://nuget.codeplex.com/SourceControl/latest#src/CommandLine/Common/PackageExtractor.cs):
public static void InstallPackage(IPackageManager packageManager, IPackage package)
{
var uniqueToken = GenerateUniqueToken(packageManager, package.Id, package.Version);
// Prerelease flag does not matter since we already have the package to install and we ignore dependencies.
ExecuteLocked(uniqueToken, () => packageManager.InstallPackage(package, ignoreDependencies: true, allowPrereleaseVersions: true));
}
Note the hard call to ignoreDependencies: true

Creating NuGet package with reference to a non-NuGet reference

I am creating a Class Library that builds 2 dlls into a NuGet package. It has a few references to dlls that currently do not have a NuGet package to be referenced from.
How should I make my NuGet package dependent on those dlls that are currently unavailable via NuGet?
If I bundle them up as well, what happens if a project that already has a reference to these dlls, pulls down my NuGet package, what happens to that reference?
Should I just create a NuGet package for each dll reference and make my NuGet package dependent on these?
You can bundle the DLLs into your NuGet package with no ill effects. A project that already has those DLLs in some /libs (or whatever) folder will continue to reference them from there. Assemblies in your NuGet package will reference the bundled DLLs that are pulled into /packages.
In your nuspec file, use the <file> element to include the internal DLLs, as such:
<package>
<metadata>
...
</metadata>
<files>
<file src="PATH_TO_BIN\DependencyOne.dll" target="mylibs" />
<file src="PATH_TO_BIN\DependencyTwo.dll" target="mylibs" />
</files>
</packages>
This will result in the following file structure when the NuGet package is pulled:
PATH_TO_PROJECT/packages/YOUR_NUGET_PACKAGE/mylibs/DependencyOne.dll
PATH_TO_PROJECT/packages/YOUR_NUGET_PACKAGE/mylibs/DependencyTwo.dll
The target attribute can specify any arbitrary path relative to your package root.