库是否应该明确针对.NET Core 3?

时间:2019-09-08 22:21:10

标签: .net-core nuget nuget-package .net-core-3.0

在.NET Standard 2.0发行版中,即使您已经以1.x为目标,也建议将.NET Standard 2.0作为目标。

https://docs.microsoft.com/en-us/dotnet/standard/net-standard

  

但是,针对较低的.NET Standard版本,引入了许多支持依赖项。如果您的项目针对.NET Standard 1.x,我们建议您也针对.NET Standard 2.0。这简化了在.NET Standard 2.0兼容框架上运行的库用户的依赖关系图,并减少了他们需要下载的软件包数量。

现在,另一个重大变化即将到来! .NET Core 3,我看到Microsoft 也将.NET Core 3定位为Microsoft软件包。

例如,Microsoft.Extensions.Logging面向.NET Standard 2.0和.NET Core 3(.NETCoreApp 3.0):

enter image description here

我比较了XML文件,并且两个API看起来都一样(也许不是比较它们的最佳方法)

现在是问题;)

作为依赖于Microsoft.Extensions.Logging(试图支持.NET Core 3)的库维护者: 我是否还应该以.NET Core 3为目标?或者,如果我不需要.NET Core 3的特定内容,仅.NET Standard 2.0就足够了吗?

3 个答案:

答案 0 :(得分:1)

简短答案

如果不想使用.NET Core 3,或者不想提供任何.NET Core 3优化,则不必以.NET Core 3为目标。另一方面,双重定位不会花费您任何费用,并且可以让您摆脱现在内置于.NET Core 3中的库引用。至少,您也许可以摆脱现在已经存在的一些库引用。运行时附带。

好答案

这完全取决于您在做什么,想做什么。库没有没有定位到.NET Core 3.0,只是因为其依赖项已将其包含在目标中。

例如,the source code 显示Microsoft.Extensions.Logging似乎没有任何C#8 / .NET Core 3.0特定代码。它以3.0为目标,因为它是这一波扩展的一部分,因此双重目标无需任何修改。

另一方面,Config.Json不必引用System.Text.JsonSystem.Threading.Tasks.Extensions,因为它们是运行时的一部分。

  <ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
    <Reference Include="System.Text.Json" />
    <Reference Include="System.Threading.Tasks.Extensions" />
  </ItemGroup>

其他好处

对于维护人员,.NET Core 3.0 / .NET Standard 2.1提供了很多的健全性保护功能,例如:

  • 可空引用类型。您将在自己的代码中避免很多NRE。您可能还会捕获很多隐藏的错误。
  • 默认接口成员。将新成员添加到公共界面时,您不必担心会破坏用户的代码。
  • IAsyncEnumerable。不再等待一堆异步操作的所有结果
  • 开关表达式以及更强大的模式匹配和解构语法。

对于某些功能,您只能添加仅适用于.NET Core的几种方法。例如,ChannelReader class在部分文件中添加单个ReadAllAsync()方法,该方法从通道读取项目并返回IAsyncEnumerable<>,例如:

    public virtual async IAsyncEnumerable<T> ReadAllAsync([EnumeratorCancellation] CancellationToken cancellationToken = default)
    {
        while (await WaitToReadAsync(cancellationToken).ConfigureAwait(false))
        {
            while (TryRead(out T item))
            {
                yield return item;
            }
        }
    }

这是一个很小但非常方便的添加方式。它使您可以使用:

接收消息
await foreach(var msg from reader.ReadAllAsync())
{
   ....
}

另一方面,即使对于.NET Standard 2.0,NRT也将有所帮助,因为它们可以帮助您在为.NET Core 3.0进行编译时在源代码中捕获可空性错误。

答案 1 :(得分:1)

  

作为依赖于库的维护者   试图支持.NET Core 3的 Microsoft.Extensions.Logging。   我还应该以.NET Core 3为目标-还是.NET Standard 2.0很好   如果我不需要.NET Core 3的特定内容就足够了吗?

在您的库中定位.NET Standard 2.0就足够了,只要您的所有依赖项也都针对.NET Standard 2.0,包括Microsoft.Extensions.Logging

Panagiotis Kanavos said一样,为您的库的使用者定位.NET Core 3.0可能会有好处,因此,如果是这种情况并且花费不多,那么就一定要针对.NET Core。 .NET Standard 2.0之外的3.0。

karann said一样,nuget始终会为图中的每个包选择最匹配的资产。即

  • App A使用您的库并以.NET Core 3.0为目标。您的库仅针对.NET Standard 2.0。 NuGet会使用它,这很好。
  • App A使用您的库并以.NET Core 3.0为目标。您的库同时面向.NET Standard 2.0和.NET Core 3.0。 NuGet将选择.NET Core 3.0

答案 2 :(得分:0)

当有人安装软件包时,NuGet会使用TFM中与项目的TFM最匹配的资产。它也对传递依赖项执行此操作。

例如-如果项目目标netcore30和程序包A的资产在lib / netcore30和lib / netstandard20下,则nuget将选择lib / netcore30。假设程序包A依赖于B,而程序包B拥有netstandard20,net472的资产,nuget将选择netstandard20。

最重要的是,nuget将为图中的每个程序包选择最匹配的资产。因此,作为库维护者,您无需添加两个TFM以支持netcore30。您可以根据此文档https://docs.microsoft.com/en-us/dotnet/standard/net-standard

定位netstandard21,这意味着它支持netcore30。