.NET 标准、.NET 核心、PCL

Posted

技术标签:

【中文标题】.NET 标准、.NET 核心、PCL【英文标题】:.NET Standard, .NET Core, PCL 【发布时间】:2016-12-27 07:34:14 【问题描述】:

.NET Standard 是一个令人困惑的概念。标准 .NET 库格式的想法听起来很棒。但是,尚不清楚它到底是什么。 Visual Studio 中现在有 .NET Core 和 .NET Standard 类库项目模板,以及旧的 PCL 项目。我还发现,如果您进入项目的设置,您可以将现有的 PCL 库切换到 .NET Standard。不清楚 .NET 标准是否是一个库?或 DLL 格式。

我要问的基本问题是我们应该针对哪种类型的库?我主要是为 Xamarin 项目做这件事,但如果我们可以与其他人共享这些库,那就太好了平台,尤其是 .NET Core 和 UWP。令人困惑的是,为什么微软会同时推出两种看似相同的类库类型:.NET Core 和 .NET Standard。

定义

NET Core - 一个基于 .NET 的运行时环境,符合 .NET Standard API 定义。

PCL - 一种基于 .NET 的库格式,受多种运行时环境支持,包括 .NET、Mono、UWP 等

.NET Standard(定义 1) - 基于 .NET 的运行时环境的一组标准 API 定义

.NET 标准(定义 2) - 一种基于 .NET 的库格式,受多种运行时环境支持,包括 .NET、Mono、UWP 等,它是 PCL 格式的延续。在 Visual Studio 中,通过进入项目的属性并编辑目标框架,可以将 PCL 库转换为 .NET Standard 库。

【问题讨论】:

阅读docs.microsoft.com/dotnet/articles/standard/library 忘记 PCL,因为它很快就会消失。 .NET Standard 是一个标准,所以在您的情况下,您应该从 1.0 开始创建一个针对某个 .NET Standard 的 .NET Core 库。玩它,概念就会自己解释。 我最近试过这个。但是,我发现 Xamarin 项目不会接受 .NET Standard dll 作为引用。 这篇文章解释了为什么 .NET Standard 仍然相关:christianfindlay.com/2020/12/21/net-standard 【参考方案1】:

这方面的文档确实比较混乱,但大致可以这样理解:

PCL:针对一组平台的库(具有这些平台的 API 的“最小公分母”)。所以在编写 PCL 时,您是说我想针对平台 A、B、C

.NET 标准:一组“标准”API,而不是一个平台。所以基本上你不关心平台,只关心标准(版本 1.3、1.6 ...),你的代码将在支持它的所有平台上工作。

.NET 核心在这里不要混淆,它是 .NET 框架的“另一个版本”。 .NET 标准将跨运行时工作(.NET 框架、.NET 核心、Mono)

所以我想.NET 标准是要走的路:)

【讨论】:

虽然这很有意义,但这与您实际上可以获取 PCL 库项目并将其快速转到 .NET Standard 的事实不一致。而且,此时您必须选择 .NET Standard 版本。真正让我困惑的是我实际编译成什么格式?我什至不知道。【参考方案2】:

我相信此资源可以回答您的大部分问题:

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

.NET 标准库是 .NET API 的正式规范,旨在用于所有 .NET 运行时。标准库背后的动机是在 .NET 生态系统中建立更大的统一性。

据我了解,其他库类型是特定于平台的,而 .NET 标准在某种程度上与平台无关。

如果您希望您的代码在不同平台上可用,那么 .NET 标准似乎是理想的,但请密切注意其他平台支持的 .NET 标准版本(参见链接中的表格)。

希望对你有帮助

【讨论】:

大多数人没有意识到的是,.net 标准共享运行时,但不共享基类库。当您使用 .net 标准库时,您会将库所需的 System.* dll 拉入您的应用程序。这会导致您的部署规模增加。 PCL 或完整的 .net dll 不是这种情况。【参考方案3】:

来自 Samuel Englard (https://github.com/dotnet/corefx/issues/973#issuecomment-249582799):

.NET DLL 根据 ECMA-335 进行格式化(通常称为 公共语言基础设施)。这种格式适用于所有 我们称之为 .NET 的平台;完整框架、核心、Xamarin、Mono、 银光等。

您不能使用针对一个平台编译的 DLL 的原因 另一个是格式没有指定API(一般来说)。 因此,虽然他们都可以读取 DLL,但您会遇到类问题 XYZ 位于一个平台上的命名空间 A.B.C 和命名空间 D.E.F 上 另一个,如果它存在的话。

PCL 通过做两件事“解决”了这个问题:

他们使用了类型转发,因此即使您在命名空间 A.B.C 中编写了期望类 XYZ 的代码,也可以在其他地方拥有它的平台上找到它。 它将您可以使用的 API 限制为您想要的所有平台共享的最低通用集。

采用 PCL 并将其转换为 .NET Standard 项目并不是一件容易的事 由于输出格式但由于元数据而重新编译 包括(特别是类型转发)。

所以,我认为本质上 .NET Standard 库与 PCL 库没有什么不同,只是它们在不同的标准化 API 集之上放置了一个层,并且这些 API 可能实现不同的指针(类型转发) .

.NET Core 当然是一个运行时环境,但我认为它与 .NET Standard 非常接近。除了实现 .NET Standard API 之外,我认为它与它没有任何特殊关系。

In my mind, it is generally better to target a .NET Standard Class library because this will be compatible across multiple platforms。例如,如果您以 .NET Core 为目标,则无法在 UWP 中引用此程序集类型。你会看到:

但是,如果您在纯 .NET Core 环境中工作,您可能会发现有特定于 .NET Core 运行时环境的 API 可用,因此有必要以 .NET Core 为目标直接。

请参阅此词汇表: https://github.com/dotnet/corefx/blob/master/Documentation/project-docs/glossary.md

【讨论】:

我还想看看github.com/dotnet/corefx/blob/master/Documentation/project-docs/… 以帮助更好地解决问题:) 我已经和一位 netfx 团队成员谈过了。他说,如果代码无法理解,基于 netstandard 的库将无法在每个平台上运行。例如,您可以编写 netstandard 代码来打开一个文件,该文件将存在于 windows 上,但不存在于 linux 上。 Nuget 不会告诉您刚刚安装的包将不兼容 - 例如 - 您的 Xamarin android 项目。 Nuget 仍然允许您添加包,因为您的项目也支持 netstandard。这意味着您不能再依赖 nuget 来检查包的兼容性。一个新的恐怖世界即将来临! 这就是为什么您需要选择正确版本的 .NET Standard 库以匹配您正在构建的平台。【参考方案4】:

标准用于针对类似于 Android API 版本的特定 API 集。 nuget 库只是包含所有符合标准的库的元包。

MSDEV 节目中的 Scott Hunter 很好地解释了这个概念。值得一试 - http://msdevshow.com/2016/07/dot-net-core-with-scott-hunter/

【讨论】:

以上是关于.NET 标准、.NET 核心、PCL的主要内容,如果未能解决你的问题,请参考以下文章

在 .net 核心应用程序中加载标准库

从 .net 核心控制台应用程序引用 .net 标准 2.0 库中的 dll 时出错

如何将 PC 转换为基于 .net 标准的库

如何从 DBContext(实体框架核心)中的 App.config(不是 .net 核心应用程序)读取值

ASP.NET 核心 CORS 标头未显示

Aurelia 的 Oauth2 托管在 asp .net 核心中