如何打包 .NET Framework 库?

How to package a .NET Framework library?

如何以现代通用方式打包 .NET 库以通过 NuGet 发布?假设我有一个 AnyCPU 程序集,希望在 .NET Framework 4.6 平台上可用。

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:

您需要创建并发布包含以下内容的 NuGet 包:

  • 包含您的代码 (.dll) 的程序集。
  • 调试符号文件 (.pdb)。
  • XML 文档文件 (.xml),假设您已在项目设置中启用它。

虽然发布您的代码的原因很明显,但其他两个值得扩展:

  • 调试符号文件使运行时能够使用代码的行号填充堆栈跟踪,并且还可以向附加的调试器提供附加信息。将此文件包含在 NuGet 包中是增强与您的库相关的故障排除体验的一种非常简单的方法。
  • XML documentation file 被 Visual Studio 用来显示工具提示,为您的库的用户提供有关方法及其参数的文档。这避免了必须引用外部文档,提高了库的可用性。

本质上,NuGet 包是一个包含您的内容和一些元数据的 zip 文件。要发布此 .NET 库,您需要创建一个具有以下结构的包(省略元数据):

\---lib
    \---net46
            MyLibrary.dll
            MyLibrary.pdb
            MyLibrary.XML

简而言之,当将包安装到 .NET Framework 4.6 项目中时,将使用 lib\net46 中的所有内容,而这正是您所需要的。所有三个文件都将来自发布构建配置下项目的构建输出目录。

创建此类 NuGet 程序包的最简单方法是使用 NuGet 命令行可执行文件。在您的解决方案中创建一个目录(例如 MyLibrary\NuGet)并将 nuget.exe 复制到该目录中。要定义库的 NuGet 包的结构,请在同一目录(例如 MyLibrary.nuspec)中创建一个 .nuspec 文件,使用以下内容作为模板:

<?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>

确保将 nuget.exe 和 .nuspec 文件的构建操作设置为 None,以避免构建过程不必要地触及它们。

如果您的项目是根据标准 Visual Studio 项目模板配置的,您项目的所有三个相关输出(MyLibrary.dll、MyLibrary.xml 和 MyLibrary.pdb)都将是存在于 bin\Release 目录中,示例中的通配符模式会将它们全部复制到 NuGet 包中的适当位置。

依赖项列表应该反映项目目录中的 packages.config 文件。如果你的库不依赖于其他 NuGet 包,你可以简单地省略 <dependencies> 元素。

在继续之前使用发布配置构建您的解决方案。

您可以使用命令 nuget.exe pack MyLibrary.nuspec 创建包。这将生成一个以 .nuspec 文件中指定的 ID 命名的包,例如Example.MyLibrary.1.0.0.nupkg。您可以将此文件上传到您选择的 NuGet 包存储库,然后像使用任何其他 NuGet 包一样直接继续使用它。

我发现使用 PowerShell 脚本启动 NuGet 程序包生成是有益的,尤其是当您需要执行 pre-processing 内容时,更复杂的项目通常就是这种情况。下面是一个 PowerShell 脚本示例,它将在同一目录中使用 nuget.exe 为同一目录中的所有 .nuspec 文件创建包:

# 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"
}

如果您将它包含在您的项目中,请确保将 PowerShell 脚本的构建操作设置为 None,以避免构建过程不必要地触及它。

示例库和相关打包文件为available on GitHub。这个答案对应的解决方案是SimpleNetFrameworkLibrary.