Embed vs reference my dependencies: Best practices for .NET/NuGet package? - c#

I'm providing a C#/.NET class library to clients within my company as a NuGet package. My library depends upon some other 3rd-party libraries (e.g. Newtonsoft's excellent Json.NET).
I'm assuming that the standard way NuGet works is that my package would only include references to other NuGet packages I depend upon. The client's Developer Studio will automatically download them when they install my NuGet package in their project.
Question #1:
Can I be certain that Developer Studio will download the versions of
those NuGet packages that I was building against and not the 'latest'
versions?
Question #2:
Will it cause problems if their project also uses a 3rd-party library
that I'm using (like Json.NET), especially if they are using a different version? Does this 'just work', or do I need to do something about this?
Apologies if this is spelled out somewhere, but I've not been able to find specific answers to these questions.

That's clearly laid out in the Nuspec Reference
Specifically:
Specifying Dependencies
Starting from version 2.0, package dependencies can be specified to vary according to the framework profile of the target project. The element contains a set of elements. Each group contains zero or more element and a target framework attribute. All dependencies inside a group are installed together if the target framework is compatible with the project's framework profile.
<dependencies>
<group>
<dependency id="RouteMagic" version="1.1.0" />
</group>
<group targetFramework="net40">
<dependency id="jQuery" />
<dependency id="WebActivator" />
</group>
<group targetFramework="sl30">
</group>
</dependencies>
Where version is:
The range of versions acceptable as a dependency. Typically this is
just a version number which represents a minimum version. However a
more explicit version range syntax is supported.
(update: updated references to more recent version of nuget)

Related

Where is PackageReference located in console application C#

I have came across this line of code in a code and its quite confusing
One of my client send a dependancy file that contains
<ItemGroup>
<PackageReference Include="xyzrefrence" Version="1.3.0" />
and said it is console application. I created same kind of application but within packages.config
I found this thing
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="xyz" version="1.7.7.7" targetFramework="net452" />
My question is that where the dependacy file located with the client setting(First settings)
The reference (<ItemGroup><PackageReference.....) to the dependency can be
found by editing the Visual Studio project file. *.csproj
The dependency file itself can be found in your project's /bin/debug or /bin/release folders.
Where is PackageReference located in console application C#
There are two nuget mamangement format(Packages.config and PackageReference) to intall nuget packages.
In fact, PackageReference is a new nuget management format for new sdk projects(net standard and net core) since VS2017 while Packages.config is an old tranitional nuget management format for net framework projects.
However, you should note that for traditional framework projects, Microsoft made a concession to use the new SDK's pacakgeReference format, but there are still various compatibility issues.--------(net frameowork projects can use both of them while net core/net standard projects can only use PackageReference).
If you use a net framework project, you can change these two format before you install nuget packages at the beginning by Tools-->Options-->NuGet Package Manager-->General-->Package Management.
And you should specifiy this format before you install the first nuget package at the beginning and when you specify this format, the nugets you install later will use this method by default and cannot be changed.
My question is that where the dependacy file located with the client
setting(First settings)
1) If you use a net framework console project with PackageReference, l am afraid that you cannnot see the depenencies of the nuget. The old sdk projects with PackageReference does not support showing the depenencies of the nuget packages due to several compatibility issues.
2) If you use a net core console project, you can see the dependencies in the Solution Explorer and the latest new sdk projects does support this. It has a new behavior that you can see every nuget package's depenencies under its branch in the Soluton Explorer.
Besides, since you use a framework project with packages.config, you can only see all of them(the premise is that this nuget package has dependencies.) in the packages.config file or in the xxxx.csproj file but it cannot subdivide dependencies for every nuget package.
In additon, if you still want to show the depenencies of the net framework projects with PackageReference, l suggest you could post a feature request in our User Voice forum(DC)-suggest a feature to get Micorosft's attention.

Resolving nuget package references

I am writing an app which needs to load nuget packages dynamically (it uses Roslyn to scan for documentation, type information, etc).
I have a situation where I want to load the following package (info derived from a csproj file):
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<AssemblyName>J4JSoftware.Logging</AssemblyName>
<RootNamespace>J4JSoftware.Logging</RootNamespace>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" />
</ItemGroup>
The challenge is that my system's nuget cache does not have an assembly/DLL for a netstandard2.0 version of Serilog.Sinks.Console 3.1.1 (I don't think one exists online, either). All it has is one for netstandard1.3.
Yet the app that I'm scanning (i.e., the one with the requirement for Serilog.Sinks.Console 3.1.1 netstandard2.0) works perfectly fine. So the package requirement is being resolved, I presume, to the netstandard1.3 version...even though the project is netstandard2.0.
Questions:
what's the best place for documentation on how nuget packages are resolved at runtime? Perhaps I could duplicate the resolving function in my scanning app.
better yet, is there a library that handles the resolution automagically? Perhaps something that's part of nuget itself? I studied the nuget github project but didn't see such a thing, but I don't pretend to be a nuget expert.
I would do something like: nuget update or nuget list and interact from C# etc with the console. That way you are sort of getting a library like behavior but not baking your own code that may break across nuget versions.
NetStandard 1.3 is likely usable for Netstandard 2.0 as mentioned here (but not the other way around).
Nuget versioning would declare that you want say Netstandard 2.0 and the package you are using might say it supports NetStandard 1.3+ (which includes Netstandard 2.0 implicitly). Nuget will select the highest one provided that suites your needs, in this case probably 1.3 as you indicated. Details are here on how nuget selects dependencies. I assume that this is the same way in how it determines runtime folders.

Does Nuget automatically create package with PackageReference'd dependencies?

I have a .NET 4.5.2 library using Visual Studio 2017 (v 15.9.7).
In my library project (i.e. csproj), I've added a Nuget dependency on CEFSharp for WPF (which itself includes other dependencies).
I've converted my library Nuget references to use the newer "PackageReference" mode.
When running nuget pack from the command line, I expect that the created *.nupkg would automatically include references to the CEFSharp components that my library references.
It doesn't look like this is the case. When I open the nupkg as a zip, I can't see any references to CEFSharp.
Do I really need to make my library's nuspec file redundantly declare the CEFSharp dependency even though my csproj already essentially defines the CEFSharp dependency?
If you're generating your nuget from a nuspec file then yes, this file must declare the dependencies to other nugets. For instance:
<dependencies>
<group>
<dependency id="CefSharp.Wpf" version="71.0.0" exclude="Build,Analyzers" />
</group>
</dependencies>

Nuget pinning versions

I'm working on a C# project in Visual Studio 2013 where we develop many nuget packages to be consumed in multiple different applications. We have encountered some nuget.org packages where we want to "pin" to an old version, and have that expression of the old version of the package be centralized.
For example, we are not compatible with Unity 4 or NUnit 3, so we want to stick to the prior releases of those packages.
I don't like using "allowedVersions" in packages.config, because
it's not centralized (every project will have to have this entered)
The GUI in Visual around updating packages at the solution level ignores project level "allowedVersions"
I've played around with expressing the version pinning in a root level nuget package that had a .nuspec with dependency lines like this
<dependency id="Unity" version="(,4.0)" />
<dependency id="NUnit" version="(,3.0)" />
which seems to block all consumers from advancing to an unsupported version. I like this because it's simple and I can just tell my teammates to make sure every package includes that root level nuget package.
The one things I don't like is that every consumer of this root package will get a reference to packages that they don't necessarily use.
For example, my released application will now have a reference to NUnit, despite not using it at all.
Is there a way that I can express version pinning in Nuget without getting these unnecessary dependencies?

Nuget packages.config and specific version

I am trying to create a Nuget package from my project following this guide http://docs.nuget.org/docs/creating-packages/creating-and-publishing-a-package
I have successfully created a nuspec and nupkg. My project contains a dependency to Json.NET which I installed via Nuget. However, I want to specify a specific version of Json.NET to use, version 4.0.7. I added the below to my nuspec:
<dependencies>
<dependency id="Newtonsoft.Json" version="[4.0.7]" />
</dependencies>
When I run nuget pack it seems to detect I have a packages.config
Using 'MyProject.nuspec' for metadata.
Found packages.config. Using packages listed as dependencies.
This seems to completely ignore my defined dependency in the nuspec as installing the Nuget package lists the dependencies as >= 4.0.7 which pulls in the latest version 4.0.8.
How can I stop this or preferably keep Nuget pulling in dependencies from the packages.config but allow me to overwrite specific dependencies?
I hit the same issue. You need to define an exact version like this
<dependencies>
<dependency id="Newtonsoft.Json" version="[4.0.7,4.0.7]" />
</dependencies>
So that will ensure when the project pulls in the dependencies it will be = 4.0.7 not >= 4.0.7
The way you specified your version is correct; as shown in our versioning docs, [1.0] means 'version == 1.0'. The behavior you're describing would be a bug, but I couldn't reproduce the bug. What I did:
Created a class library
Added Json.NET via NuGet (it installed 4.0.8)
Exec'd nuget spec
Added <dependencies><dependency id="Newtonsoft.Json" version="[4.0.7]" /> to the .nuspec
Exec'd nuget pack
Opened the package in Package Explorer; it shows the dependency as '= 4.0.7'
Installed my package in a new project; it shows the dependency as '= 4.0.7' and installs 4.0.7
Perhaps you aren't using the latest version of nuget.exe or the NuGet Visual Studio extension? When you say it "lists the dependency", where are you seeing that? When your package is installed, in Package Explorer, or somewhere else?

Categories