在类库开发中,如何设定多个 .net 框架目标

因为现在 .net 版本比较多,但不是所有 .net 版本都可以向下兼容(具体可参见:https://docs.microsoft.com/zh-cn/dotnet/standard/net-standard

但有一些公共纯逻辑与平台无关代码希望能够可以打包为 nuget 包,被各种项目引用。甚至即便与平台相关,但是可以根据不同平台进行不同实现的需求。

以下以 .net framework 4 和 .net standard 2.0 项目共享为例,实际可以扩展到任意 .net 版本:

1、使用 .net standard 2.0 创建一个类库项目

尽量使用高版本 .net 框架(通过 PackageReference 管理引用)进行创建来兼容低版本的(通过 package.config 管理引用)

低版本也不是不能改,就是需要从 package.config 迁移到 PackageReference,就更复杂了

参考文档:https://docs.microsoft.com/zh-cn/nuget/consume-packages/package-references-in-project-files

image

2、新建项目后,在解决方案管理器的项目上点右键,选择编辑项目文件

image

3、在打开的项目文件中,将原有的 TargetFramework 节点替换为 TargetFrameworks,然后在节点中增加需要的目标框架,改完如下所示:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <!-- 声明需要的目标框架 -->
    <TargetFrameworks>netstandard2.0;net40</TargetFrameworks>
  </PropertyGroup>

  <!-- 通过条件输出注释文件到不同路径 --> 
  <PropertyGroup Condition="'$(Configuration)'=='Release'">
    <DocumentationFile>binRelease$(TargetFramework)$(MSBuildProjectName).xml</DocumentationFile>
  </PropertyGroup>

  <!-- 在 .NET Framework 4.0 目标框架下需要引用的项目 -->
  <ItemGroup Condition="'$(TargetFramework)' == 'net40'">
    <Reference Include="System.Net" />
    <COMReference Include="NetFwTypeLib">
      <Guid>{58FBCF7C-E7A9-467C-80B3-FC65E8FCCA08}</Guid>
      <VersionMajor>1</VersionMajor>
      <VersionMinor>0</VersionMinor>
      <Lcid>0</Lcid>
      <WrapperTool>tlbimp</WrapperTool>
      <Isolated>False</Isolated>
      <EmbedInteropTypes>True</EmbedInteropTypes>
    </COMReference>
  </ItemGroup>

  <!-- 在 .NET Standard 2.0 目标框架下需要引用的项目 -->
  <ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
    <PackageReference Include="Microsoft.Windows.Compatibility" Version="5.0.2" />
  </ItemGroup>
</Project>

除了修改 TargetFrameworks 以外,对于未来添加的非通用的引用,都需要在 ItemGroup 下通过 TargetFrameWork 进行条件控制引用

在 VS 界面添加的引用,默认是通用的,不区分目标框架,可以在添加完成后,再编辑项目文件进行手动调整

关于项目定义文件中的可使用的变量,似乎在不同的编译阶段也不尽相同,基本都是靠参考自动生成的内容或者从网上查找相关示例。

大概查到了以下几个文档地址:

MSBuild:

https://docs.microsoft.com/zh-cn/visualstudio/msbuild/msbuild-properties

https://docs.microsoft.com/zh-cn/visualstudio/msbuild/msbuild-reserved-and-well-known-properties

4、到此为止,也就完成了项目的多目标框架配置,可以在项目依赖项中看到多目标框架的各自引用内容:

image

在编辑源代码时,可以通过左上角切换不同的目标框架,以检查代码的错误:

image

不知道为什么没有在 VS 界面中实现以上需要手动配置的复杂操作,也许是逻辑太复杂了吗。。。

5、最后就是在代码中,如果需要有针对各自平台的逻辑,可以通过 #if … #endif 编译条件进行判断屏蔽

imageimage

在不同目标框架下,预设的条件也不同,但需要注意的是,这里的条件仅代表目标框架,并不表示实际运行平台(比如 Windows 或 Linux),对于平台逻辑的判断还需要额外进行判断。

参考文档:https://docs.microsoft.com/zh-cn/dotnet/core/tutorials/libraries#how-to-multitarget


输了你,赢了世界又如何...
原文地址:https://www.cnblogs.com/xwgli/p/14760603.html