如何为 nuget 包构建具有多个 .net 框架的项目

How can I build a project with multiple .net frameworks for nuget package

我正在 github 上开发一个项目并发布到 nuget。我创建的每个版本都必须构建多个 .net 框架并将这些 dll 用于 nuget 包。有没有一种简单的方法来发布所有这些 .net 框架版本? 谢谢。

  1. 目标框架名字对象 (TFM) 兼容性

存在 TFM 兼容性。通常,较低版本的 TFM 系列与较高版本兼容。因此,.NET Framework 4.7 程序集可用于面向 .NET Framework 4.7.1、4.7.2 或 4.8 的项目。同样,面向 .NET Standard 1.2 的 NuGet 包可用于面向 .NET Standard 2.0 的项目。

.NET Standard 也很特别。这不是 运行time,而是 运行times 实施的规范。就像the docs on .NET Standard说的,虽然.NET 4.6.1被标记为兼容.NET Standard 2.0及以下版本,但还是有问题,所以建议至少使用.NET Framework 4.7.2或4.8正在使用包,或项目参考,以 .NET Standard 为目标。

最后,.NET Core 的 运行time、netcoreapp 和 .NET Framework 之间的 API 有很大的重叠。因此,即使存在不兼容性,为了让 .NET Core 应用程序使用可能不兼容的 NuGet 包,.NET Core SDK 2.0 引入了一个称为目标回退的概念。如果项目与包不直接兼容,并且包支持其中一个目标后备 TFM,NuGet 将允许它并发出警告。它可能会在 运行 时失败,因此会出现警告,但它可能会起作用。这对于 .NET Core 3.0 更为重要,开发人员在 WPF 和 WinForms 中编写桌面应用程序,希望使用提供桌面功能的 .NET Framework NuGet 包。

总而言之,您可能不需要创建面向多个 TFM 的 NuGet 包。只是 select 具有您需要的 API 的最低 TFM,以它为目标,并让 TFM 兼容性使其发挥作用。但是,如果您想使用仅在较新的 TFM 中可用的 API,同时仍支持较旧的 TFM,那么您将需要多目标您的项目和包,但同样,您可以尽量减少需要支持的 TFM 的数量。您的包裹不需要 netstandard1.0netstandard1.1netstandard1.2netstandard1.3netstandard2.0netstandard2.1 TFM。

  1. 使用 SDK 风格的项目

假设您正在使用 Visual Studio 进行开发,请安装 .NET Core 工作负载,即使您不打算进行跨平台(Linux、Mac)开发。使用 .NET Core,项目文件变得更加简单,同时功能也更加强大,包括对在单个项目文件中定位多个 TFM 的内置支持。以前有必要为您想要的每个 TFM 在您的包中创建一个 csproj,编译每个项目,然后有一个 nuspec 将所有内容拉入正确的位置。现在,只需一个 csproj 即可列出您要定位的所有 TFM,以及 运行 dotnet pack(不要创建 nuspec,the package metadata come from MSBuild properties)。

因此,安装 .NET Core SDK 后,您可以从 Visual Studio 创建 .NET Standard class 库,或者 运行 dotnet new classlib命令行。如果您想以 .NET Framework 为目标,创建 .NET Standard class 库并不重要,因为这就是您获得 SDK 样式项目的方式。 .NET Framework class 库项目模板使用不支持多目标的非 SDK 样式项目。然后编辑 csproj 并将 <TargetFramework>netstandard2.0</TargetFramework> 更改为 <TargetFrameworks>net472;netstandard2.0</TargetFrameworks>。请注意,TargetFramework(单数)变为 TargetFrameworks(复数),并且 XML 元素的内容是 TFMs you want your project to target).

的分号分隔列表

这是一个完整的 csproj 示例,您可以从以下开始:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFrameworks>net472;netstandard2.0</TargetFrameworks>
    <CheckForOverflowUnderflow>true</CheckForOverflowUnderflow>
  </PropertyGroup>

</Project>

如前所述,一旦你有一个看起来像这样的 csproj,只需从命令行 运行 dotnet pack(你也可以右键单击 Visual Studio's Solution Explorer,和 select Pack),你会得到一个 nupkgnet472netstandard2.0 都在包中的正确位置编译了程序集.

您将以下代码用于多个 .net 框架,如 .Net Core 3.1 或更高版本:

<Project Sdk="Microsoft.NET.Sdk">
    <PropertyGroup>
        <TargetFrameworks>netstandard2.0;netcoreapp3.1</TargetFrameworks>
        <GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
      </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.1.7" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.1.7">
      <PrivateAssets>all</PrivateAssets>
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    </PackageReference>
  </ItemGroup>

  <ItemGroup>
    <ProjectReference Include="..\OnlineShoppingCart\OnlineShoppingCart.csproj" />
  </ItemGroup>

</Project>