How do I package a .NET library in a modern general-purpose way for publishing via NuGet? Let's assume I have a single AnyCPU assembly that I wish to make available on the .NET Framework 4.6 platform.
This is a series of questions and answers that document my findings on the topic of modern NuGet package authoring, focusing especially on the changes introduced with NuGet 3. You may also be interested in some related questions:
- How to package a .NET library targeting the Universal Windows Platform?
- How to package a portable .NET library targeting .NET Core?
- How to package a .NET library targeting .NET Framework and Universal Windows Platform and include platform-specific functionality?
- How to package a multi-architecture .NET library that targets the Universal Windows Platform?
- How to package a .NET library that targets the Universal Windows Platform and depends on Visual Studio extension SDKs?
You can use an existing . NET Framework Class Library project for the code you want to package, or create a simple one as follows: In Visual Studio, choose File > New > Project, select the Visual C# node, select the "Class Library (. NET Framework)" template, name the project AppLogger, and click OK.
You will want to create and publish a NuGet package with the following contents:
While the reason for publishing your code is obvious, the other two are worth expanding on:
A NuGet package is, in essence, a zip file with your content plus some metadata. To publish this .NET Library, you will need to create a package with the following structure (metadata omitted):
\---lib
\---net46
MyLibrary.dll
MyLibrary.pdb
MyLibrary.XML
Simply put, everything in lib\net46 will be used when the package is installed into a .NET Framework 4.6 project and that's exactly what you need. All three files will come from your project's build output directory under the Release build configuration.
The easiest way to create such a NuGet package is using the NuGet command line executable. Create a directory in your solution (e.g. MyLibrary\NuGet) and copy nuget.exe into this directory. To define the structure of your library's NuGet package, create a .nuspec file in the same directory (e.g. MyLibrary.nuspec), using the following as a template:
<?xml version="1.0"?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata minClientVersion="3.2">
<id>Example.MyLibrary</id>
<version>1.0.0</version>
<authors>Firstname Lastname</authors>
<description>Example of a simple .NET Framework 4.6 library.</description>
<dependencies>
<dependency id="Newtonsoft.Json" version="8.0.1" />
</dependencies>
</metadata>
<files>
<file src="..\bin\Release\MyLibrary.*" target="lib\net46" />
</files>
</package>
Make sure to set the build action of nuget.exe and the .nuspec file to None, to avoid them being needlessly touched by the build process.
If your project is configured according to the standard Visual Studio project templates, all three relevant outputs of your project (MyLibrary.dll, MyLibrary.xml and MyLibrary.pdb) will be present in the bin\Release directory and the wildcard pattern in the example will copy all of them to the appropriate locations in the NuGet package.
The list of dependencies should mirror the packages.config file in your project directory. If your library has no dependencies on other NuGet packages, you can simply omit the <dependencies>
element.
Build your solution using the Release configuration before proceeding.
You can create the package using the command nuget.exe pack MyLibrary.nuspec
. This will generate a package named with the ID specified in the .nuspec file, e.g. Example.MyLibrary.1.0.0.nupkg. You can upload this file to your NuGet package repository of choice and proceed directly to using it as you would any other NuGet package.
I find that it is beneficial to use a PowerShell script to kick off NuGet package generation, especially if you need to perform pre-processing of the contents, as is often the case with more complex projects. Here is an example of a PowerShell script that will use nuget.exe in the same directory to create packages for all .nuspec files in the same directory:
# Delete any existing output.
Remove-Item *.nupkg
# Create new packages for any nuspec files that exist in this directory.
Foreach ($nuspec in $(Get-Item *.nuspec))
{
.\NuGet.exe pack "$nuspec"
}
If you include it in your project, make sure to set the build action of the PowerShell script to None, to avoid it being needlessly touched by the build process.
A sample library and the relevant packaging files are available on GitHub. The solution corresponding to this answer is SimpleNetFrameworkLibrary.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With