此答案基于principles used to package libraries targeting the .NET Framework。首先阅读链接的答案以更好地理解以下内容。
要发布可移植的 .NET 库,您需要创建具有以下结构的 NuGet 包:
\---lib
\---dotnet
MyPortableLibrary.dll
MyPortableLibrary.pdb
MyPortableLibrary.XML
所有三个文件都将来自您的项目在 Release 构建配置下的构建输出目录。
上述结构中的dotnet 目录有一个特殊的含义——它向NuGet 表明该目录中的文件将在您的包的所有依赖项都兼容的任何平台上使用。因此,您的包可自动在支持所有依赖项的任何 .NET 平台(例如 .NET Core)上使用。
关键的下一步是确定依赖项列表。由于a package management issue,不可能简单地声明对 .NET Core 本身的依赖(.NET Core 是所有 .NET 平台共享的 API 表面)。相反,您必须手动确定每个 .NET Core 组件依赖项并将其添加到 nuspec 文件中。
.NET Core 包的依赖检测过程包括两个步骤:
- 确定您的库引用的 .NET Core 程序集。
- 确定包含这些程序集的 NuGet 包。
Visual Studio 不提供您需要的信息。相反,您需要构建您的库并检查生成的 DLL 文件。以下 PowerShell 脚本将显示 .NET 程序集的引用:
Get-ChildItem MyPortableLibrary.dll | % { [Reflection.Assembly]::LoadFile($_.FullName).GetReferencedAssemblies() | % { $_.Name + ".dll" } }
此命令的输出将是程序集名称列表,例如:
System.Runtime.dll
System.Resources.ResourceManager.dll
System.Numerics.Vectors.dll
获得列表后,打开项目目录中的 project.lock.json 文件。此文件包含有关项目使用的所有 NuGet 包的信息。除了其他数据之外,您还会发现各种 JSON 块,如下所示:
"System.Numerics.Vectors/4.1.0": {
"dependencies": {
"System.Globalization": "[4.0.10, )",
"System.Resources.ResourceManager": "[4.0.0, )",
"System.Runtime": "[4.0.20, )",
"System.Runtime.Extensions": "[4.0.10, )"
},
"frameworkAssemblies": [
"mscorlib",
"System.Numerics"
],
"compile": {
"ref/net46/System.Numerics.Vectors.dll": {}
},
"runtime": {
"lib/net46/System.Numerics.Vectors.dll": {}
}
},
此 JSON 块表示“编译”下列出的程序集文件由顶级值中列出的包提供(System.Numerics.Vectors 版本 4.1.0)。使用此信息将每个引用的程序集映射到 NuGet 包。请注意,虽然包和程序集名称通常相同,但情况并非总是如此!
对于任何不属于 .NET Core 的 NuGet 包,您可以跳过上述过程,因为您已经知道您所依赖的确切包。此处描述的依赖检测逻辑只是必需的,因为由于上面链接的问题,您无法直接在 .NET Core(Microsoft.NETCore 包)上声明依赖。
现在只需根据以下示例列出 nuspec 文件中的所有依赖项:
<?xml version="1.0"?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata minClientVersion="3.2">
<id>Example.MyPortableLibrary</id>
<version>1.0.0</version>
<authors>Firstname Lastname</authors>
<description>Example of a portable library with NuGet package dependencies.</description>
<dependencies>
<dependency id="System.Numerics.Vectors" version="4.1.0" />
<dependency id="System.Resources.ResourceManager" version="4.0.0" />
<dependency id="System.Runtime" version="4.0.20" />
</dependencies>
</metadata>
<files>
<file src="..\bin\Release\MyPortableLibrary.*" target="lib\dotnet" />
</files>
</package>
就是这样!生成的包可在任何兼容的 .NET 平台上使用,例如 .NET Framework 4.6 或通用 Windows 平台。请记住在创建 NuGet 包之前使用发布配置构建您的解决方案。
一个示例库和相关的打包文件是available on GitHub。这个答案对应的解决方案是 PortableLibrary。
请参阅Lucian Wischik's blog 以更深入地了解在此类 NuGet 包上运行的逻辑。