【发布时间】:2020-01-19 13:41:39
【问题描述】:
我正在 github 上开发一个项目并发布到 nuget。我创建的每个版本都必须构建多个 .net 框架并将这些 dll 用于 nuget 包。有没有一种简单的方法可以发布所有这些 .net 框架版本? 谢谢。
【问题讨论】:
标签: c# dll frameworks nuget publish
我正在 github 上开发一个项目并发布到 nuget。我创建的每个版本都必须构建多个 .net 框架并将这些 dll 用于 nuget 包。有没有一种简单的方法可以发布所有这些 .net 框架版本? 谢谢。
【问题讨论】:
标签: c# dll frameworks nuget publish
存在 TFM 兼容性。通常,TFM 系列的低版本与高版本兼容。因此,.NET Framework 4.7 程序集可用于面向 .NET Framework 4.7.1、4.7.2 或 4.8 的项目中。同样,可以在面向 .NET Standard 2.0 的项目中使用面向 .NET Standard 1.2 的 NuGet 包。
.NET Standard 也很特别。它不是运行时,它是运行时实现的规范。就像the docs on .NET Standard 说的,虽然.NET 4.6.1 被标记为兼容.NET Standard 2.0 及以下,但还是有问题,所以建议至少使用.NET Framework 4.7.2 或4.8 使用包,或项目参考,以 .NET Standard 为目标。
最后,.NET Core 的运行时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 包。只需选择具有您需要的 API 的最低 TFM,以它为目标,并让 TFM 兼容性使其工作。但是,如果您想使用仅在较新的 TFM 中可用的 API,同时仍支持较旧的 TFM,那么您将需要多目标您的项目和包,但同样,您可以最大限度地减少需要支持的 TFM 的数量。你的包不需要netstandard1.0、netstandard1.1、netstandard1.2、netstandard1.3、netstandard2.0和netstandard2.1 TFM。
假设您使用 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 类库,或者在命令行上运行 dotnet new classlib。如果您想以 .NET Framework 为目标,创建 .NET Standard 类库并不重要,因为这就是您获得 SDK 样式项目的方式。 .NET Framework 类库项目模板使用不支持多目标的非 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 的解决方案资源管理器中右键单击该项目,然后选择打包),然后你' 将得到一个 nupkg,net472 和 netstandard2.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>
【讨论】: