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

Gig*_*igi 78 c# msbuild csproj .net-core visual-studio-2017

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

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

在此输入图像描述

Abo*_*boo 100

您需要将s添加到默认的TargetFramework并基本上将其更改为TargetFrameworks.然后你提到Moniker有一个; 分隔器.

您也可以手动或使用VS Nuget Package Manager将Nuget包引用放在条件ItemGroup中.

这是你的.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>
Run Code Online (Sandbox Code Playgroud)

我最近因为缺少文档而做的另一个解决方法是我在VS2015中创建一个项目并使用可用的文档和intellisense形成project.json,然后在VS2017中打开解决方案并使用内置升级.然后我将查看csproj文件以了解如何进行配置.

在没有Moniker的情况下多针对更多深奥的目标:

微软:

不推荐使用PCL +

虽然支持PCL,但包作者应该支持netstandard..NET平台标准是PCL的演变,代表了跨平台的二进制可移植性,使用的单个名字与静态类似,如portable-a + b + c标记.

如果你想针对便携式个人资料不具有预定义的绰号所以便携式配置文件也不能推断TargetFrameworkIdentifier,TargetFrameworkVersionTargetFrameworkProfile.此外,未自动定义编译器常量.最后,您必须添加默认情况下未提供的所有程序集引用.

下面的示例来自使用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>
Run Code Online (Sandbox Code Playgroud)

  • 我遇到了同样的问题,将s添加到&lt;TargetFramework&gt;后,一切工作正常。真希望这些东西能得到更好的记录。 (2认同)
  • @AsadSaeeduddin很有可能Resharper向你展示了曲线而不是Visual Studio.$(TargetFramework)仅用于使ItemGroup可用于特定框架/ Moniker. (2认同)
  • @ORMapper 如果 NuGet 包构建正确,这应该在您导入时自动发生。这意味着如果 NuGetPackageA 已经支持多个框架,则无需将其放入条件项组中。现在,如果您需要为 .net 框架引用 PackageA,为 .net core 引用 PackageB,则需要将其放入条件项组。截至今天(2017 年 10 月),界面中没有选项。 (2认同)

Nig*_*ker 23

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

<TargetFrameworks>net451;netstandard1.4</TargetFrameworks>
Run Code Online (Sandbox Code Playgroud)

例如,请参阅EFCore.csproj:https: //github.com/aspnet/EntityFrameworkCore/blob/951e4826a38ad5499b9b3ec6645e47c825fa842a/src/EFCore/EFCore.csproj

  • 谢谢!它杀了我.在Brian Kernigan的四十年前编写的"编程风格的元素"中,他谈到了使用最后一个字母不同的变量的错误.如果名称是"TargetFrameworkList",那将会更加清晰. (8认同)

Han*_*ant 11

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

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

您可以通过使用"类库(.NET标准)"项目模板启动项目来完成此操作.您现在可以选择选择.NETStandard版本.当前兼容性网格在这里.

希望他们能够更新该链接文章.这是不稳定的,.NETStandard 2.0已被确定,但尚未发布.针对2017年第二季度,春季结束,目前显示为97%完成.我无意中听到设计师说不建议使用1.5或1.6,与2.0不兼容

  • @HansPassant多目标仍然是最好的选择,如果您有遗留代码,同时您的绿地开发可以在最近的完整框架风格或dotnetcore之一完成. (4认同)

Chr*_*oll 6

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

最简单的方法是:

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

然后

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

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