是否有任何可靠的(甚至是标准化的)方法来创建同时支持多个目标框架的 .NET 库?

Is there any reliable (even standardized) approach to creating a .NET library that supports multiple target frameworks simultaneously?

我知道这是一个很笼统的问题,但我无法找到解决以下情况的可靠资源,也没有找到一个地方。所以我决定在这里提问,希望能帮助其他遇到同样问题的人:

作为 .NET 组件的开发人员,我希望支持各种 .NET 目标框架。当 dot net coredot net standard 被引入时,随着最近目标框架变体的爆炸式增长,这个话题对我来说变得非常重要。

所以,假设我正在编写一个编译为 MyLib.dll 的 C# 库 MyLib(我称之为 "product")。我想支持不同范围的目标框架:net35net40net45netstandard1.2 等。因此我为每个目标创建构建(MSBuild 或 csproj 文件)框架并将它们捆绑在一个 nuget 包中,遵守 nuget guidelines for the lib folder structure。因此,产品可以从单个构建工件——nuget 包中获得。

对于每个目标框架版本,我都尝试利用它的特性和优势,并为较低版本提供 pollyfills 或剥离一些特性。一般来说,要点是 "product" 是可用的,无论消费项目的目标框架如何——我的意思是 MyLib 的 nuget 包应该正确安装,并且应该引用适当的 dll。

所以,出现了几个问题:

到目前为止,我自己的方法是为相同的每个目标框架使用一个单独的 .csproj 文件 "product",但是随着开发的进行,支持多个项目可能会变得乏味,即使作为目标框架数量现在非常重要。

Therefore I create builds (MSBuild or csproj files) for each target framework and bundle them together in a single nuget package.

如果您使用 Visual Studio 2017 年的新 csproj "SDK" 格式,那么您甚至不需要这样做 - 它支持多个目标框架。例如:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
   <TargetFrameworks>net451;netstandard1.3</TargetFrameworks>
  </PropertyGroup>
</Project>

此项目同时支持 .NET Framework 4.5.1 和 NETStandard1.3。

这会自动创建条件编译符号,因此您可以执行 #if NET451#if NETSTANDARD1_3 之类的操作,以便在需要时有条件地应用代码。您同样可以在 .csproj 本身中执行此操作,以便仅包含一个框架的 nuget 包。 Dapper 项目在他们的 .csproj 文件中有一个这样的例子。

使用新的 dotnet cli,您可以使用 dotnet pack 将其全部打包到一个 nuget 包中。