How to package a .NET Framework library? [closed]

You will want to create and publish a NuGet package with the following contents:

  • The assembly containing your code (.dll).
  • The debug symbol file (.pdb).
  • The XML documentation file (.xml), assuming you have enabled it in project settings.

While the reason for publishing your code is obvious, the other two are worth expanding on:

  • The debug symbol file enables the runtime to populate stack traces with the line numbers of your code and may also provide additional information to an attached debugger. Including this file in the NuGet package is a very simple way to enhance the troubleshooting experience associated with your library.
  • The XML documentation file is used by Visual Studio to display tooltips that provide documentation about methods and their arguments to users of your library. This avoids having to reference an external piece of documentation, increasing usability of your library.

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="https://stackoverflow.com/questions/34611829/..\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.

Leave a Comment