在类库开发中,如何设定多个 .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>bin\Release\$(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

posted @   不是豆豆  阅读(4026)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
历史上的今天:
2015-05-12 未能加载文件或程序集“Microsoft.SqlServer.Management.Sdk.Sfc, Version=11.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91”或它的某一个依赖项。系统找不到指定的文件。
友情链接:迷途


点击右上角即可分享
微信分享提示