Microsoft.Extensions.* 版本混淆

kim*_*gro 6 asp.net-core

我有一个库目标netstandard2.0,我在ASP.NET Core 2.2依赖几个Microsoft.Extensions包的应用程序中使用它

这是我的 csproj

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>netstandard2.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="2.2.0" />
    <PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="2.2.0" />
  </ItemGroup>

</Project>
Run Code Online (Sandbox Code Playgroud)

我现在希望能够在新ASP.NET Core 3应用程序和现有ASP.NET Core 2.2应用程序中使用相同的库。

查看Microsoft.Extensions.*软件包,它们的版本似乎总是与ASP.NET Core.

我的选择是

  • 什么都不做.. 这个包还能在ASP.NET Core 3应用程序中工作吗?
  • 3.0将这些软件包升级到它们的等效版本 .. 这个软件包在ASP.NET Core 2应用程序中仍然有效吗?
  • 保留现有包(用于ASP.NET Core 2.2应用程序),但3.0使用ASP.NET Core 3.0应用程序中使用的等效项创建新包

总体问题是作为库作者,Microsoft.Extensions.*包的特定版本与其在特定ASP.NET Core目标中的使用之间有什么关联?

Tse*_*eng 1

您可以(并且应该)进行多目标定位。

目标netstandard2.0netstandard2.1,以供netstandard2.0参考 2.x(适合您的最低版本,概率 2.0,2.x 中不应有重大更改)和netstandard2.1参考 3.x 版本。

为什么?

因为它是一个主要版本跳跃,通常以新的 api、删除旧的或更改方法签名(换句话说:重大更改)结束,并且由于netstandard2.1需要 .NET Core 3.0,因此引用它的应用程序也依赖于Microsoft.Extensions.*3.x 版本 APi 表面

要有条件地引用包,请执行以下操作

<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' ">
     <PackageReference Include="Microsoft.Extensions.Logging" Version="2.0"/>
</ItemGroup>

<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.1' ">
     <PackageReference Include="Microsoft.Extensions.Logging" Version="3.0"/>
</ItemGroup>
Run Code Online (Sandbox Code Playgroud)

或者

<PackageReference Include="Microsoft.Extensions.Logging" Version="2.0" Condition=" '$(TargetFramework)' == 'netstandard2.01' "/>
<PackageReference Include="Microsoft.Extensions.Logging" Version="3.0" Condition=" '$(TargetFramework)' == 'netstandard2.1' "/>
Run Code Online (Sandbox Code Playgroud)

也可以,但可读性较差。这仍然会创建一个 NugetPackage,但它将有两个文件netstandard2.0netstandard2.1两个针对不同版本的单独编译的程序集。

当此包在 .NET Core 3 上恢复时,它将使用该netstandard2.1版本,如果在 .NET Core 2.x 上恢复,它将使用netstandard2.0.

如果存在 api 差异,则必须在代码中使用预处理器指令

#if NETSTANDARD2_0
    // API call of 2.x library
#elif NETSTANDARD2_1
    // Api call of 3.x library
#endif
Run Code Online (Sandbox Code Playgroud)