zoukankan      html  css  js  c++  java
  • 一个csproj文件指定多个开发框架

    本文转自waterlv

    SDK-Style的工程文件参考https://docs.microsoft.com/zh-cn/dotnet/core/sdk?view=aspnetcore-5.0

    前言

    可移植类库、共享项目、.NET Standard 项目都能够帮我们完成跨多个 .NET SDK 的单一项目开发,但它们的跨 SDK 开发都有些限制。

    现在,我们又有新的方式能够跨多个 .NET SDK 开发了,这就是使用新的 csproj 文件格式。

    看看拥有多个开发框架的项目长什么样吧!

    多 SDK 的项目
    ▲ 多 SDK 项目

    这个是在 GitHub 上开源项目 dotnet-campus/MSTestEnhancer 的项目依赖截图。

     

    SDK 风格的 csproj 文件

           使用共享项目的方式则是直接共享了源码,只要在目标项目中指定了条件编译符,那么源码便能针对各种不同的目标框架进行分别编译。但缺点是对扩展插件的支持较差(可能是因为扩展插件难以判断项目的真实开发框架),

    而且 Visual Studio 本身对它的支持也有 BUG(例如切换编写文件所属的项目经常会失败)。

           新的 csproj 文件能够指定多个开发框架。这样,我们便能同时编写适用于 .NET Framework 4.5 的和 .NET Standard 2.0 的代码,同时还能够得到 Visual Studio 和扩展插件较好的支持。

    .NET Standard 和 .NET Core 项目在创建之时就已经是新的 csproj 格式了,但 .NET Framework 项目、UWP/WPF 项目依然使用旧风格的 csproj 文件。对于 .NET Framework 项目,可以通过 将 WPF、UWP 以及其他各种类型的旧 csproj 迁移成 Sdk 风格的 csproj - walterlv 一文进行迁移。

    不过对于 WPF/UWP 项目,根本就没有跨多个 SDK 的必要,就不要改了……

    如果是新开项目——强烈建议先按照 .NET Standard 项目类型建好,再修改成多开发框架。

    如何指定多个开发框架

    只要是 Sdk 风格的 csproj 文件,指定多个开发框架真的是相当的简单。

    <Project Sdk="Microsoft.NET.Sdk">
      <PropertyGroup>
        <TargetFrameworks>net45;netstandard2.0</TargetFrameworks>
      </PropertyGroup>
      <!-- 这个文件里的其他内容 -->
    </Project>

    请特别注意!!!TargetFramework 从单数形式变为了复数形式 TargetFrameworks!!!这个时候,TargetFramework 是编译时自动指定的。

    如果是对以上多框架的项目进行单元测试,考虑到编译的目标平台是多个的,单元测试项目也需要指定多个目标框架。

    <Project Sdk="Microsoft.NET.Sdk">
      <PropertyGroup>
        <TargetFrameworks>net471;netcoreapp2.0</TargetFrameworks>
        <IsPackable>false</IsPackable>
      </PropertyGroup>
      <!-- 这个文件里的其他内容 -->
    </Project>

    多框架项目的坑以及如何避坑

    微软的官方文档 How to: Configure Projects to Target Multiple Platforms - Microsoft Docs 中只说了如何指定多个目标框架,并没有提及指定了多框架以后的坑。

    如果多开发框架中包含了低版本的 .NET Framework,例如 4.0/4.5 等,那么这些坑才比较容易凸显——因为这些版本的 .NET Framework 与 .NET Standard 的第三方库差异较大。所以,我们需要有方法来解决其第三方库引用的差异。这时需要在 csproj 文件中指定包含条件。例如:

    <Project Sdk="Microsoft.NET.Sdk">
      <PropertyGroup>
        <TargetFrameworks>net471;netcoreapp2.0</TargetFrameworks>
        <OutputType Condition="'$(TargetFramework)'!='netcoreapp2.0'">Exe</OutputType>
        <IsPackable>false</IsPackable>
      </PropertyGroup>
    
      <!-- 这里的引用是二者共有的 -->
      <ItemGroup>
        <PackageReference Include="MSTest.TestAdapter" Version="1.2.0" />
        <PackageReference Include="MSTest.TestFramework" Version="1.2.0" />
      </ItemGroup>
    
      <!-- 这里的引用用于非 .NET Core 框架 -->
      <ItemGroup Condition="'$(TargetFramework)'!='netcoreapp2.0'">
        <PackageReference Include="Xxx" Version="1.0.*" />
      </ItemGroup>
    
    
      <!-- 这里的引用用于 .NET Core 框架 -->
      <ItemGroup Condition="'$(TargetFramework)'=='netcoreapp2.0'">
        <PackageReference Include="Yyy" Version="1.0.*" />
      </ItemGroup>
    
    </Project>

    在 dotnet-campus/MSTestEnhancer 项目中,只有 .NET Framework 4.5 才需要引用 System.ValueTuple,于是加上了 net45 条件判断:

    <!--EXTERNAL_PROPERTIES: TargetFramework-->
    <ItemGroup Condition="'$(TargetFramework)'=='net45'">
      <PackageReference Include="System.ValueTuple" Version="4.4.0" />
    </ItemGroup>

    那段注释的作用是告诉代码分析工具 TargetFramework 是外部属性,上下文环境中找不到这个属性是正常的。

  • 相关阅读:
    Spring MVC 3.0.5+Spring 3.0.5+MyBatis3.0.4全注解实例详解(四)
    中国B2B行业将进入后平台时代
    做产品经理 而不是功能经理(转淘宝鬼脚七)
    全球最值的学习的100个网站
    gridview 内的button 用法
    框架内 FRAME的源src如何根据条件而变化?C#解决方案
    一般中小企网络出口的后备线路(adsl做后备)
    Windows server 2012_远程_没有远程桌面授权服务器可以提供许可证
    访问网站返回常见的状态码200,404等表示什么意思(转)
    站长学习 一 Robots简单认识
  • 原文地址:https://www.cnblogs.com/xietianjiao/p/15023403.html
Copyright © 2011-2022 走看看