.NET Core 和 .NET Standard Class 库项目类型有什么区别?

What is the difference between .NET Core and .NET Standard Class Library project types?

在 Visual Studio 中,您至少可以创建三种不同类型的 class 库:

虽然第一个是我们多年来一直使用的,但我一直感到困惑的一个主要问题是何时使用 .NET Standard 和 .NET Core class 库类型。我最近在尝试 , and .

时被这个问题困扰了

那么,Class库(.NET Standard)Class库(.NET Core)有什么区别,为什么两者都存在,我们什么时候应该使用一个而不是另一个?

When should we use one over the other?

该决定是兼容性和 API 访问之间的权衡。

当您想要增加与您的库兼容的应用程序数量时,请使用 .NET Standard 库,并且您可以接受减少您的库可以访问的 .NET API 表面积.

当您想要增加您的库可以访问的 .NET API 表面区域时使用 .NET Core 库,并且您可以只允许 .NET Core 应用程序与您的库兼容。

例如,以 .NET Standard 1.3 will be compatible with applications that target .NET Framework 4.6, .NET Core 1.0, Universal Windows Platform 10.0, and any other platform that supports .NET Standard 1.3. The library will not have access to some parts of the .NET API, though. For instance, the Microsoft.NETCore.CoreCLR 包为目标的库与 .NET Core 兼容,但与 .NET Standard 不兼容。

What is the difference between Class Library (.NET Standard) and Class Library (.NET Core)?

兼容性:面向 .NET Standard 的库将 运行 在任何符合 .NET Standard 的 运行 时间,例如 .NET Core、.NET Framework Mono/Xamarin。另一方面,面向 .NET Core 的库只能 运行 在 .NET Core 运行 时间。

API Surface Area:.NET Standard 库包含 NETStandard.Library 中的所有内容,而 .NET Core 库包含 Microsoft.NETCore.App 中的所有内容。后者包括大约 20 个额外的库,其中一些我们可以手动添加到我们的 .NET Standard 库中(例如 System.Threading.Thread),还有一些与 .NET Standard 不兼容(例如 Microsoft.NETCore.CoreCLR ).

此外,.NET Core 库指定 运行时间并附带应用程序模型。这很重要,例如,使单元测试 class 库 运行 可用。

Why do both exist?

暂时忽略库,.NET Standard 存在的原因是为了可移植性;它定义了 .NET 平台同意实施的一组 API。任何实现 .NET Standard 的平台都与面向该 .NET Standard 的库兼容。其中一个兼容平台是 .NET Core。

回到库,.NET Standard 库模板存在 运行 多次 运行 次(以 API 表面积为代价)。相反,.NET Core 库模板的存在是为了访问更多 API 表面积(以牺牲兼容性为代价)并指定用于构建可执行文件的平台。

Here is an interactive matrix 显示哪个 .NET 标准支持哪个 .NET 实现以及有多少 API 表面积可用。

.NET.NET Core是.NET运行时代的两种不同实现。 Core 和 Framework(但尤其是 Framework)都有不同的配置文件,其中包括 Microsoft 为 .NET 创建的许多 APIs 和程序集中更大或更小(或完全不同)的选择,具体取决于它们的安装位置和在什么配置文件。

例如,与“普通”Windows 配置文件相比,通用 Windows 应用程序中有一些不同的 API 可用。即使在 Windows 上,您也可能拥有“客户端”配置文件与“完整”配置文件。此外,还有其他实现(如 Mono)有自己的库集。

.NET Standard 是一种规范,API 库和程序集集必须可用。为 .NET Standard 1.0 编写的应用程序应该能够编译 运行 任何版本的 Framework、Core、Mono 等,宣传支持 .NET Standard 1.0 库集合。 .NET Standard 1.1、1.5、1.6、2.0 等也是如此。只要 运行time 为您的程序所针对的 Standard 版本提供支持,您的程序就应该 运行。

针对标准版本的项目将无法使用该标准修订版中未包含的功能。这并不意味着您不能依赖其他程序集或其他供应商发布的 APIs(即:NuGet 上的项目)。但这确实意味着您采用的任何依赖项还必须包括对您的 .NET Standard 版本的支持。 .NET Standard 正在快速发展,但它仍然足够新,并且足够关心一些较小的 运行 时间配置文件,因此这种限制可能让人感到窒息。 (注意一年半后:这开始发生变化,最新的 .NET Standard 版本更好,功能更全)。

另一方面,针对标准 的应用应该 能够在更多部署情况下使用,因为理论上它可以 运行 与核心、框架、Mono 等。对于寻求广泛分发的 class 库项目,这是一个有吸引力的承诺。对于主要面向内部受众的以最终用户为中心的项目,这可能不是什么大问题。

.NET Standard 在系统管理员团队希望从 Windows 上的 ASP.NET 迁移到 [=43= 上的 .NET Core 的 ASP.NET 的情况下也很有用] 出于哲学或成本原因,但开发团队希望在 Visual Studio 和 Windows 上继续针对 .NET Framework 工作。

简短的回答是:

IAnimal == .NetStandard (General)
ICat == .NetCore (Less general)
IDog == .NetFramework (Specific / oldest and has the most features)

.NET Core Class 库 建立在.NET 标准 之上。如果你想实现 table 到 .NET Framework.NET Core 的库Xamarin,选择一个 .NET 标准库

.NET Core 最终将实现 .NET Standard 2Xamarin.NET Framework)

因此,可以识别

.NET CoreXamarin.NET Framework作为 flavours of .NET Standard

为了 future-proof 您的代码共享和重用应用程序,您宁愿实施 .NET Standard 库。

Microsoft 还建议您使用 .NET Standard 而不是 Portable Class Libraries.

引用 MSDN 作为权威来源,.NET Standard 旨在成为 统一库。图片抵千字,下面就很清楚了:

1.您目前的应用场景(碎片化)

像我们大多数人一样,您可能处于以下情况: (.NET Framework、Xamarin 和现在的 .NET Core 风格的应用程序)

2。 .NET 标准库将为您启用什么(cross-framework 兼容性)

实施 .NET 标准库允许在所有这些不同风格之间共享代码:

不耐烦的人:

  1. .NET Standard 通过在您需要的环境中提供您期望和喜爱的所有 API,解决了所有平台上 .NET 开发人员的代码共享问题:桌面应用程序,移动应用和游戏以及云服务:
  2. .NET Standard 一组 API 所有 .NET 平台 必须实施。这 统一了 .NET 平台 并且 防止了未来的碎片化
  3. .NET Standard 2.0 将由 .NET Framework、.NET Core 实现, 和 Xamarin。对于 .NET Core,这将添加许多现有的 API 已请求。
  4. .NET Standard 2.0 包含 .NET Framework 二进制文件的兼容性垫片,显着增加了可引用的库集您的 .NET Standard 库。
  5. .NET Standard 将替换 Portable Class 库 (PCL) 作为 构建 multi-platform .NET 库的工具故事。

为了 table 帮助了解您可以针对的最高版本的 .NET Standard,基于您打算 运行 的 .NET 平台,head over here

来源:MSDN: Introducing .NET Standard

.NET Standard 的存在主要是为了改进代码共享并使每个 .NET 实现中可用的 API 更加一致。

在创建库时,我们可以将目标设为 .NET Standard 2.0,这样创建的库将与不同版本的 .NET Framework 兼容,包括 .NET Core、Mono

.NET Standard:将其视为一个大型标准库。将其用作依赖项时,您只能制作库 (.DLL),而不能制作可执行文件。可以将使用 .NET 标准作为依赖项创建的库添加到 Xamarin.Android、Xamarin.iOS、.NET Core Windows/OS X/Linux 项目。

.NET Core:将其视为旧 .NET 框架的延续,只是它是开源的,有些东西尚未实现,有些则已弃用。它用额外的功能扩展了 .NET 标准,但它只能在 desktops 上运行。将其添加为依赖项时,您可以在 Windows、Linux 和 OS X 上创建可运行的应用程序。(尽管目前只有控制台,没有 GUI)。所以 .NET Core = .NET Standard + 桌面特定的东西。

此外 UWP uses it and the new ASP.NET Core 也将其用作依赖项。

.NET Framework 和.NET Core 都是框架。

.NET Standard 是一个标准(换句话说,一个规范)。

您可以使用 .NET Framework 和 .NET Core 创建可执行项目(如控制台应用程序或 ASP.NET 应用程序),但不能使用 .NET Standard。

使用 .NET Standard,您只能创建一个 class 库项目,该项目不能独立执行,应该被另一个 .NET Core 或 .NET Framework 可执行项目引用。

我希望这有助于理解 .NET Standard API 表面与其他 .NET 平台之间的关系。每个接口代表一个目标框架,方法代表该目标框架上可用的 API 组。

namespace Analogy
{
    // .NET Standard

    interface INetStandard10
    {
        void Primitives();
        void Reflection();
        void Tasks();
        void Xml();
        void Collections();
        void Linq();
    }

    interface INetStandard11 : INetStandard10
    {
        void ConcurrentCollections();
        void LinqParallel();
        void Compression();
        void HttpClient();
    }

    interface INetStandard12 : INetStandard11
    {
        void ThreadingTimer();
    }

    interface INetStandard13 : INetStandard12
    {
        //.NET Standard 1.3 specific APIs
    }

    // And so on ...


    // .NET Framework

    interface INetFramework45 : INetStandard11
    {
        void FileSystem();
        void Console();
        void ThreadPool();
        void Crypto();
        void WebSockets();
        void Process();
        void Drawing();
        void SystemWeb();
        void WPF();
        void WindowsForms();
        void WCF();
    }

    interface INetFramework451 : INetFramework45, INetStandard12
    {
        // .NET Framework 4.5.1 specific APIs
    }

    interface INetFramework452 : INetFramework451, INetStandard12
    {
        // .NET Framework 4.5.2 specific APIs
    }

    interface INetFramework46 : INetFramework452, INetStandard13
    {
        // .NET Framework 4.6 specific APIs
    }

    interface INetFramework461 : INetFramework46, INetStandard14
    {
        // .NET Framework 4.6.1 specific APIs
    }

    interface INetFramework462 : INetFramework461, INetStandard15
    {
        // .NET Framework 4.6.2 specific APIs
    }

    // .NET Core
    interface INetCoreApp10 : INetStandard15
    {
        // TODO: .NET Core 1.0 specific APIs
    }
    // Windows Universal Platform
    interface IWindowsUniversalPlatform : INetStandard13
    {
        void GPS();
        void Xaml();
    }

    // Xamarin
    interface IXamarinIOS : INetStandard15
    {
        void AppleAPIs();
    }

    interface IXamarinAndroid : INetStandard15
    {
        void GoogleAPIs();
    }
    // Future platform

    interface ISomeFuturePlatform : INetStandard13
    {
        // A future platform chooses to implement a specific .NET Standard version.
        // All libraries that target that version are instantly compatible with this new
        // platform
    }

}

Source

解释差异的另一种方法是使用真实世界的示例,因为我们大多数人都会使用现有的工具和框架(Xamarin, Unity 等)来完成工作。

因此,借助 .NET Framework,您可以使用所有 .NET 工具,但您只能针对 Windows 个应用程序(UWP, Windows Forms, ASP.NET,等等)。由于 .NET Framework 是封闭源代码,因此没有什么可做的。

使用 .NET Core 时,您拥有的工具较少,但您可以针对主要的 桌面平台(Windows、Linux 和 Mac).这在 ASP.NET 核心应用程序中特别有用,因为您现在可以在 Linux 上托管 ASP.NET(更便宜的托管价格)。现在,由于 .NET Core 是开源的,因此在技术上可以为其他平台开发库。但由于没有支持它的框架,我认为这不是一个好主意。

使用 .NET Standard,您拥有的工具更少,但您可以面向 all/most 平台。多亏了 Xamarin,你可以定位 移动设备 ,多亏了 Mono/Unity,你甚至可以定位 游戏机 。也可以使用 UNO 平台和 Blazor(尽管两者现在都处于试验阶段)来定位 Web 客户端。

在实际应用程序中,您可能需要使用所有这些。例如,我开发了一个具有以下架构的 point of sale 应用程序:

同时共享服务器和客户端:

  • 一个 .NET Standard 库,用于处理我的应用程序的 模型
  • 一个 .NET Standard 库,用于处理客户端发送的数据验证。

由于它是一个 .NET Standard 库,因此可以在任何其他项目(客户端和服务器)中使用。

在 .NET 标准库上进行验证也是一个很好的优势,因为我可以确定在服务器和客户端上应用了相同的验证。服务器是强制性的,而客户端是可选的并且有助于减少流量。

服务器端(Web API):

  • 处​​理所有数据库连接的 .NET Standard(也可以是 .NET Core)库。

  • 一个处理 Rest API 并利用 数据库库。

由于这是在 .NET Core 中开发的,我可以在 Linux 服务器上托管应用程序。

客户端 (MVVM with WPF + Xamarin.Forms Android/iOS):

  • 处​​理客户端 API 连接的 .NET Standard 库。

  • 一个处理 ViewModels 逻辑的 .NET Standard 库。它用于 所有浏览量。

  • 处​​理 WPF 视图的 .NET Framework WPF 应用程序 windows申请。 WPF 应用程序现在可以是 .NET 核心,尽管它们目前仅适用于 Windows。 AvaloniaUI 是为其他桌面平台制作 desktop GUI 应用程序的一个很好的选择。

  • 处​​理 Xamarin 表单视图的 .NET Standard 库。

  • Xamarin Android 和 Xamarin iOS 项目。

所以你可以看到在应用程序的客户端这里有一个很大的优势,因为我可以重用 .NET Standard 库(client API 和ViewModels),并只为 WPF、Xamarin 和 iOS 应用程序创建没有逻辑的视图。

前面的回答可能是对.NET Core、.NET Standard 和.NET Framework 之间差异的最好理解,所以我只是想分享一下我选择这个而不是那个的经验。

在您需要混合使用 .NET Framework、.NET Core 和 .NET Standard 的项目中。例如,在我们使用 .NET Core 1.0 构建系统时,不支持 Window 使用 .NET Core 托管的服务。

下一个原因是我们使用的 Active Report 不支持 .NET Core。

所以我们想要构建一个可同时用于 .NET Core (ASP.NET Core) 和 Windows Service and Reporting (.NET Framework) 的基础结构库 -> 这就是我们选择的原因.NET Standard 用于此类库。 选择 .NET 标准意味着您需要仔细考虑库中的每个 class 应该是简单的并且跨 .NET(核心、框架和标准)。

结论:

  • .NET Standard 用于基础设施库和共享公用。这个库可以被.NET Framework 和.NET Core 引用。
  • .NET Framework 用于不受支持的技术,如 Active Report、Window 服务(现在支持 .NET 3.0)。
  • .NET Core 当然是 ASP.NET 核心。

Microsoft 刚刚发布了 .NET 5:Introducing .NET 5

.NET 框架

Windows Forms、ASP.NET 和 WPF 应用程序必须使用 .NET Framework 库开发。

.NET 标准

Xamarin、iOS 和 Mac OS X 应用程序必须使用 .NET Standard 库开发

.NET 核心

Universal Windows Platform (UWP) 和 Linux 应用程序必须使用 .NET Core 库开发。 API 是用 C++ 实现的,您可以使用 C++、VB.NET、C#、F# 和 JavaScript languages.NET

每个框架都有其 class 库。

  • .Net Framework 的基础 Class 库。
  • .Net 核心的核心库。
  • Mono Class Xamarin 库。

Microsoft 已决定将所有这些 class 库合并为一个可在所有框架中实现的库。为此,他们开发了 .Net 标准。

微软决定做一个统一的Framework。 .Net 5 是.Net core 和.Net Framework 的统一框架。在 .Net 6 中,他们也将 .Net MAUI 项目下的 Xamarin 与 .Net 合并。

.Net Framework, .Net Core, Xamarin 统一为一个Framework .Net 6,所以不需要.Net标准。 .Net 标准的目标是拥有一个适用于所有框架的库。现在所有框架都合并到 .Net 6 中。

.NET 核心 .NET Core 是托管框架的免费、跨平台、开源实现。它支持四种类型的应用程序:控制台、ASP.NET 核心、云和通用 Windows 平台 (UWP)。 Windows 表单和 Windows Presentation Foundation (WPF) 不是 .NET Core 的一部分。

从技术上讲,.NET Core 仅支持控制台应用程序。 ASP.NET Core 和 UWP 是构建在 .NET Core 之上的应用程序模型。

与 .NET Framework 不同,.NET Core 不被视为 Windows 组件。因此,更新以 NuGet 包的形式出现,而不是通过 Windows 更新。由于 .NET Core 运行时安装在 App-Local,并且应用程序通过包管理器更新,应用程序可以与特定的 .NET Core 版本相关联并单独更新。

.NET 标准 托管框架的每个实现都有自己的一组基础 Class 库。基本 Class 库 (BCL) 包含 类,例如异常处理、字符串、XML、I/O、网络和集合。

.NET Standard 是实现 BCL 的规范。由于 .NET 实现需要遵循此标准,因此应用程序开发人员不必担心每个托管框架实现的 BCL 版本不同。

框架 Class WPF、WCF 和 ASP.NET 等库 (FCL) 不是 BCL 的一部分,因此不包含在 .NET Standard 中。

.NET Standard 与 .NET 实现之间的关系与 HTML 规范与浏览器之间的关系相同。第二个是第一个的实现。

因此,.NET Framework、Xamarin 和 .NET Core 都在其托管框架中为 BCL 实现了 .NET 标准。由于计算机行业将继续引入新的硬件和操作系统,因此将有新的 .NET 托管框架。该标准让应用程序开发人员知道将有一组他们可以依赖的一致的 API。

每个 .NET 版本都有一个关联的 .NET Standard 版本。

通过提供一致的 API,将应用程序移植到不同的托管实现以及提供工具变得更加容易。

.NET Standard 被定义为单个 NuGet 包,因为所有 .NET 实现都需要支持它。工具变得更容易,因为这些工具有一组一致的 API 可用于给定版本。您还可以为多个 .NET 实现构建单个库项目。

您还可以为平台特定的 API 构建 .NET Standard 包装器。