繁体   English   中英

如何使用 csproj 多目标 .NET Core 类库?

[英]How do you multi-target a .NET Core class library with csproj?

当.NET Core 仍然使用project.json格式时,您可以构建面向多个框架(例如net451、netcoreapp1.0)的类库。

既然官方项目格式是使用 MSBuild 的csproj ,那么如何指定多个框架作为目标? 我试图寻找这个在VS2017的项目设置,但我能只针对从.NET框架的核心在单一框架(它甚至没有列出这一点已经安装了其他完整的.NET框架版本) :

在此处输入图片说明

您需要手动编辑项目文件并将s添加到默认的TargetFramework并基本上将其更改为TargetFrameworks 然后你用一个; 来提及Moniker 分隔器。

您也可以手动或使用 VS Nuget 包管理器将 Nuget 包引用放在条件项组中。

这是您的 .csproj 应该是什么样子:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFrameworks>netstandard1.6;net452</TargetFrameworks>
  </PropertyGroup>

  <ItemGroup Condition="'$(TargetFramework)' == 'net452'">
    <PackageReference Include="Microsoft.Azure.DocumentDB">
      <Version>1.12.0</Version>
    </PackageReference>
  </ItemGroup>

  <ItemGroup Condition="'$(TargetFramework)' == 'netstandard1.6'">
    <PackageReference Include="Microsoft.Azure.DocumentDB.Core">
    <Version>1.1.0</Version>
    </PackageReference>
  </ItemGroup>
</Project>

由于缺少文档,我这几天做的另一个解决方法是我在 VS2015 中创建一个项目并使用可用文档和智能感知形成 project.json,然后在 VS2017 中打开解决方案并使用内置升级。 然后我将查看 csproj 文件以找出如何进行该配置。

没有Moniker 的多目标更深奥的目标:

微软:

不推荐 PCL+

尽管支持 PCL,但包作者应该支持 netstandard。 .NET 平台标准是 PCL 的演变,代表跨平台的二进制可移植性,使用单个名字对象,该名字对象不依赖于像便携式 a+b+c 名字对象那样的静态对象。

如果您想针对便携式配置文件,它没有预定义的名字,因此便携式配置文件也无法推断TargetFrameworkIdentifierTargetFrameworkVersionTargetFrameworkProfile 编译器常量也不是自动定义的。 最后,您必须添加默认情况下不提供的所有程序集引用。

下面的这个示例取自一个使用dynamic关键字的项目,因此它额外需要Microsoft.CSharp程序集,因此您可以看到它如何引用不同的目标。

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFrameworks>netstandard1.5;net40;portable40-net45+sl5+win8+wp8</TargetFrameworks>
  </PropertyGroup>

  <PropertyGroup Condition="'$(TargetFramework)'=='portable40-net45+sl5+win8+wp8'">
    <TargetFrameworkIdentifier>.NETPortable</TargetFrameworkIdentifier>
    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
    <TargetFrameworkProfile>Profile158</TargetFrameworkProfile>
    <DefineConstants>$(DefineConstants);PORTABLE158</DefineConstants>
  </PropertyGroup>

  <ItemGroup Condition="'$(TargetFramework)'=='netstandard1.5'">
    <PackageReference Include="Microsoft.CSharp" Version="4.3.0" />
    <PackageReference Include="System.ComponentModel" Version="4.3.0" />
  </ItemGroup>

  <ItemGroup Condition="'$(TargetFramework)'=='net40'">
    <Reference Include="Microsoft.CSharp" />
  </ItemGroup>

  <ItemGroup Condition="'$(TargetFramework)'=='portable40-net45+sl5+win8+wp8'">
    <Reference Include="Microsoft.CSharp" />
    <Reference Include="System" />
    <Reference Include="System.Core" />
    <Reference Include="System.Windows" />
  </ItemGroup>
</Project>

您可以为此手动编辑.csproj文件并设置TargetFrameworks (不是TargetFramework )属性。

<TargetFrameworks>net451;netstandard1.4</TargetFrameworks>

例如,参见EFCore.csprojhttps : //github.com/aspnet/EntityFrameworkCore/blob/951e4826a38ad5499b9b3ec6645e47c825fa842a/src/EFCore/EFCore.csproj

我实际上选择了类库(.NET Core)。

如果您的库需要在多个平台目标上工作,那不是您想要的项目模板。 使用此项目模板,您的库只能在面向 .NETCore 的项目中使用。 PCL 库方法已停用,您现在必须选择 .NETStandard。

您可以通过使用“类库 (.NET Standard)”项目模板启动项目来实现。 您现在可以选择 .NETStandard 版本。 当前的兼容性网格在这里

希望他们会更新链接的文章。 这是在不断变化中,.NETStandard 2.0 已确定但尚未发布。 目标是 2017 年第二季度,可能是春末,目前显示已完成 97%。 我无意中听到设计师说不推荐使用1.5或1.6,与2.0不够兼容

我做了一个关于多目标网络框架和 netcore简单指南,它从最少 15 秒的修复开始,然后引导您完成每个复杂问题。

最简单的方法是:

  1. 首先,让 netcore 或 netstandard 目标工作。

然后

  1. 编辑 . csproj项目文件并为其他目标完成这些步骤。

    1. 更改<TargetFramework>标签<TargetFrameworks>和你的下一个目标添加到列表中,通过分隔;
    2. 了解 csproj 文件中的条件部分。 为每个目标创建一个。 使用它们来声明每个目标的依赖关系。
    3. 只需阅读构建错误消息所说的缺失内容,即可为任何网络目标添加<Reference />s for System.* dll。
    4. 如果每个目标的 NuGet <PackageReference />s依赖项不同,则处理它们。 (这里最简单的技巧是暂时恢复到单一目标,以便 GUI 只为您正确处理 Nuget 引用)。
    5. 如果您必须:学习各种创造性的技术、变通方法和节省时间的方法来处理不能在所有目标上编译的代码。
    6. 当添加更多目标的成本太高时,知道何时减少损失。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM