具有多个目标依赖项的 NuGet 包

NuGet Package with multiple target dependencies

一些 NuGet 包具有一些目标依赖项。例如,包 Microsoft.Extensions.Logging.Console 版本 3.1.3 :

https://www.nuget.org/packages/Microsoft.Extensions.Logging.Console/3.1.3

.NETCoreApp 3.1
    Microsoft.Extensions.Configuration.Abstractions (>= 3.1.3)
    Microsoft.Extensions.Logging (>= 3.1.3)
    Microsoft.Extensions.Logging.Configuration (>= 3.1.3)
.NETStandard 2.0
    Microsoft.Extensions.Configuration.Abstractions (>= 3.1.3)
    Microsoft.Extensions.Logging (>= 3.1.3)
    Microsoft.Extensions.Logging.Configuration (>= 3.1.3)

.NET 3.1 与 .NET Standard 2.0 兼容,

.NET Core 2.* 与 .NET Standard 2.0 兼容。

关于.NETStandard 2.0:根据this docu,您提到的所有目标框架(.NET Framework 4.7 和 4.8、.NET Core 2.* 和 3.*)均受支持。

我不知道 .NETCoreApp 5.0,但目前我会忽略它。也许这与 .NET 5 将成为使用 .NET Standard 2.1 的 .NET Core 3.1 的继任者有关。让我们看看最终版本何时临近......目前,它甚至没有在 corresponding docu.

中列出

编辑:

Microsoft 已发布对此进行总结的文档:


包 Microsoft.Extensions.Logging.Console 并不明显。让我们看看 Microsoft.Extensions.Identity.Core : https://www.nuget.org/packages/Microsoft.Extensions.Identity.Core/3.1.5

csproj :

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <Description>ASP.NET Core Identity is the membership system for building ASP.NET Core...</Description>
    <TargetFrameworks>netstandard2.0;$(DefaultNetCoreTargetFramework)</TargetFrameworks>
    ...
  </PropertyGroup>
  ...
</Project>

此包面向 .NET Standard 2.0 和 .NET Core 3.1(Azure DevOps 变量 $(DefaultNetCoreTargetFramework) 的值)。 发布时编译结果为:

  • bin/release/netstandard2.0/Microsoft.Extensions.Logging.Console.dll
  • bin/release/netcoreapp3.1/Microsoft.Extensions.Logging.Console.dll

生成了两个不同的 dll,但有什么区别?

查看文件 PasswordHasher.cs :

public class PasswordHasher<TUser> : IPasswordHasher<TUser> where TUser : class
{
    ...
#if NETSTANDARD2_0
    // Compares two byte arrays for equality. The method is specifically written so that the loop is not optimized.
    [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
    private static bool ByteArraysEqual(byte[] a, byte[] b)
    {
        if (a == null && b == null)
        {
            return true;
        }
        if (a == null || b == null || a.Length != b.Length)
        {
            return false;
        }
        var areSame = true;
        for (var i = 0; i < a.Length; i++)
        {
            areSame &= (a[i] == b[i]);
        }
        return areSame;
    }
#endif

    private static bool VerifyHashedPasswordV3(byte[] hashedPassword, string password, out int iterCount)
    {
        ...
        // Hash the incoming password and verify it
        byte[] actualSubkey = KeyDerivation.Pbkdf2(password, salt, prf, iterCount, subkeyLength);
#if NETSTANDARD2_0
        return ByteArraysEqual(actualSubkey, expectedSubkey);
#elif NETCOREAPP
        return CryptographicOperations.FixedTimeEquals(actualSubkey, expectedSubkey);
#else
#error Update target frameworks
#endif
    }
}

对于.NET Core 3.1,使用方法CryptographicOperations.FixedTimeEquals。但 .NET Standard 2.0 中不存在此方法。然后在Microsoft.Extensions.Identity.Core.dll中添加了一个未优化的方法ByteArraysEqual来替换缺少的方法。

当您使用包 NuGet Microsoft.Extensions.identity.Core 检查散列密码时: . .NET Core 3.1 项目,您使用特定于平台的方法 CryptographicOperations.FixedTimeEquals。 . .NET Standard 2.0 兼容项目,您使用未优化的方法 ByteArraysEqual。

问题是:

Why .NET Core 3.1 target dependencies is specify?

.NET Standard 2.0 生成的 dll 与 .NET Core 3.1 兼容并且足够了,但是针对特定平台这允许使用更优化的特定平台组件。

Can I use this package in .NET Core 2.* application? Same question to .NET 4.7 and .NET 4.8?

是的,您可以在 .NET Core 2.* 中使用此包,因为它与 .NET Standard 2.0 兼容,但您没有更优化的版本。 .NET Framework 4.7 和 .NET Framework 4.8 的相同答案