vernou
vernou

Reputation: 7590

NuGet Package with multiple target dependencies

Some NuGet packages have some target dependencies. For example, the package Microsoft.Extensions.Logging.Console version 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 is compatible with .NET Standard 2.0,

.NET Core 2.* is compatible with .NET Standard 2.0.

Upvotes: 1

Views: 1081

Answers (2)

vernou
vernou

Reputation: 7590

Edit :

Microsoft has published documentation summarizing this :


It isn't obvious for the package Microsoft.Extensions.Logging.Console. Let's look at Microsoft.Extensions.Identity.Core : https://www.nuget.org/packages/Microsoft.Extensions.Identity.Core/3.1.5

See the 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>

This package target .NET Standard 2.0 and .NET Core 3.1 (value of the Azure DevOps variable $(DefaultNetCoreTargetFramework)). The compile result in release is :

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

Two distinct dll are generated, but with what difference?

See the file 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
    }
}

For .NET Core 3.1, the method CryptographicOperations.FixedTimeEquals is used. But this method don't exists in .NET Standard 2.0. Then a not optimized method ByteArraysEqual is added in Microsoft.Extensions.Identity.Core.dll to replace the absent method.

When you use the package NuGet Microsoft.Extensions.identity.Core to check a hash password in : . .NET Core 3.1 projet, you use the platform specific method CryptographicOperations.FixedTimeEquals. . .NET Standard 2.0 compatible project, you use the not optimised method ByteArraysEqual.

Questions were :

Why .NET Core 3.1 target dependencies is specify?

The .NET Standard 2.0 generated dll is compatible with .NET Core 3.1 and can be sufficient, but target a specific platform this allows to use specific platform component that be more optimized.

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

Yes, you can use this package in .NET Core 2.* because is compatible with .NET Standard 2.0, but you don't have the more optimized version. Same answer to .NET Framework 4.7 and .NET Framework 4.8

Upvotes: 1

mu88
mu88

Reputation: 5384

Regarding .NETStandard 2.0: According to this docu, all your mentioned target frameworks (.NET Framework 4.7 and 4.8, .NET Core 2.* and 3.*) are supported.

I don't know about .NETCoreApp 5.0, but for the moment, I'd ignore it. Maybe it's related to the fact that .NET 5 will be the successor of .NET Core 3.1 which utilizes .NET Standard 2.1. Lets see when the final release comes closer... at the moment, it is not even listed in the corresponding docu.

Upvotes: 1

Related Questions