Traditionally NuGet has been a bolted-on feature. While the compiler could trigger downloading NuGet packages, it didn’t understand them. So after a package was downloaded, it needed to be installed in the project. This may include updating assembly references, copying files, or running custom PowerShell scripts. This was rather brittle, and developers occasionally needed to manually cleanup the project files before reinstalling packages.
With the new PackageReference feature, many of those problems go away. Instead of referencing individual assemblies, developers can now reference the package itself.
Package references are also transitive. This means that if you reference a package, you’re done. You don’t need to explicitly reference every package that package requires. According to the press release, this can result in a 5x improvement in performance when installing or updating packages. In one example, a 10 minute process was reduced to 30 ms.
Solution-level package folders are also eliminated. Dependencies are instead referenced directly from the user’s package cache. If you are wondering why they didn’t do this before, consider again the “bolt-on” nature of prior versions of NuGet. Since the compiler didn’t understand NuGet packages, it required that “hint paths” be set correctly in the project file. Since each user could place their package cache in a different place, using it wasn’t an option. Thus the solution-level packages folder was created, ensuring the relative hint paths were the same for all developers.
Versioning
Versioning support for NuGet project references has improved greatly. You can now use ranges and wildcards for which version of a given package you wish to use. Ranges use a mathematical syntax common:
- At least version x.y: [x.y
- Greater than version x.y: (x.y
- Version x.y or earlier: x.y]
- Earlier than x.y: x.y)
For example, if you want at least version 1.4.2 but not 1.5, you can write “[1.4.2, 1.5)”. If instead you want any version in the 1.4 family, you can say “1.4.*”.
Content can now be controlled using IncludeAssets and ExcludeAssets tags. These are used to modify which types of assets (analyzers, content files, etc.) are included in the build process. You can even tag assets as private, meaning they are used for development purposes but shouldn’t flow to down-stream libraries.
Creating NuGet Packages with MSBuild
While you could always launch NuGet’s package command from MSBuild using an Exec Command operation and passing in a specification file, it didn’t work well in a continuous integration environment. So as part of this release, MSBuild can directly package projects. It will even work with projects that target multiple frameworks using the TargetFrameworks tag.
Speaking of which, you may find the need to reference different packages based on the target platform. With PackageReference, you can include a standard MSBuild conditional expression to indicate when the reference is applicable.
Backwards Compatibility Issues
A major concern about this feature is the lack of support for some older NuGet features such as content folders, XDT transforms, and the install.ps1/uninstall.ps1 PowerShell scripts.
Currently these features are available for .NET Core and .NET Standard projects. Other project types can use it if the VS 2017 Update 1 Preview is installed..
Community comments
I feel sorry ...
by Mark N,
A typo
by Dimitrov Dimitar,
Re: A typo
by Jonathan Allen,
Re: A typo
by Jonathan Allen,
I feel sorry ...
by Mark N,
Your message is awaiting moderation. Thank you for participating in the discussion.
... for anyone having to suffer with the .NET ecosystem. I've dealt with it for years. I've not had to for 7 months.
A typo
by Dimitrov Dimitar,
Your message is awaiting moderation. Thank you for participating in the discussion.
"In one example, a 10 minute process was reduced to 30 ms."
That would have been a 5000x speedup!
Re: A typo
by Jonathan Allen,
Your message is awaiting moderation. Thank you for participating in the discussion.
That's what it says in the press release. We're waiting for an answer from the NuGet team, but I strongly suspect that it supposed to read "30 seconds".
Re: A typo
by Jonathan Allen,
Your message is awaiting moderation. Thank you for participating in the discussion.
-- Karan Nandwani, NuGet Team