.NET Core 和 .NET 标准类库项目类型有啥区别?

Posted

技术标签:

【中文标题】.NET Core 和 .NET 标准类库项目类型有啥区别?【英文标题】:What is the difference between .NET Core and .NET Standard Class Library project types?.NET Core 和 .NET 标准类库项目类型有什么区别? 【发布时间】:2017-08-13 20:20:23 【问题描述】:

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

类库 (.NET Framework) 类库(.NET 标准) 类库 (.NET Core)

虽然第一个是我们多年来一直使用的,但我一直有一个主要困惑点是何时使用 .NET Standard 和 .NET Core 类库类型。我最近在尝试multi-target different framework versions 和creating a unit test project 时被这个问题所困扰。

那么,类库(.NET Standard)类库(.NET Core)有什么区别,为什么都存在,什么时候应该使用一个比一个?

【问题讨论】:

你错过了一个:类库(便携式)。 Core == 框架,.NET Standard == 可移植。 也有一个来自 Xamarin,但这些其他的并没有为这个问题增加任何价值 :) 嗯,他们做到了。核心思想是他们放弃了可移植的方法,它从 n 中遭受了太大的痛苦! way 配置文件过多的问题。所以现在您有 7 个标准可供选择。大多数现在实际上都不是便携式的 :) .NETCore 并非遥不可及,可能还需要两年时间才能实现。 OP 说“至少有 3 种不同的类型”。帖子是准确的。 我对 Core 的命名感到困惑,它既不是标准也不是框架平台的核心子集。此外,我们经常看到 ASP 与 .Net Core 相关联。这也很混乱…… 【参考方案1】:

我们什么时候应该使用一个而不是另一个?

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

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

如果您想增加库可以访问的 .NET API 表面积,并且您可以只允许 .NET Core 应用程序与您的库兼容,请使用 .NET Core 库。

例如,以 .NET Framework 4.6、.NET Core 1.0、通用 Windows 平台 10.0 和任何其他支持 .NET Standard 1.3 的平台为目标的 .NET Standard 1.3 will be compatible with 应用程序的库。不过,该库将无法访问 .NET API 的某些部分。例如,Microsoft.NETCore.CoreCLR 包与 .NET Core 兼容,但与 .NET Standard 不兼容。

类库(.NET Standard)和类库(.NET Core)有什么区别?

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

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

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

为什么两者都存在?

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

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

Here is an interactive matrix 显示哪个 .NET Standard 支持哪些 .NET 实现以及可用的 API 表面积。

【讨论】:

很好的答案。不过还有一个问题(与 this question 相关:为什么运行单元测试需要应用程序模型?过去从未出现过这种情况,当时我们使用不可运行的类库来保存单元测试的集合。 我已经更新了对链接问题的回答。 TL;博士;过去,类库针对的是完整的框架,其中包括一个应用程序模型。 你忘了介绍类库(.NET Framework),它是否兼容 .NET Standard 和 .NET Core? This diagram 真的帮我搞定了。 @BerBar 最初的问题是关于 .NET Standard 和 .NET Core 之间的区别。这就是我省略跨平台细节的原因,因为跨平台不是 Core 和 Standard 之间的区别。我故意将我的答案限制在原始问题的范围内。【参考方案2】:

.NET Core 类库 建立在 .NET Standard 之上。如果您想实现一个可移植到 .NET Framework.NET CoreXamarin 的库,请选择 .NET 标准库

.NET Core 最终将实现 .NET Standard 2Xamarin.NET Framework 也是如此)

因此,

.NET CoreXamarin.NET Framework 可以被识别为 flavors 的 .NET 标准

为了让您的应用程序能够在未来进行代码共享和重用,您宁愿实现 .NET Standard 库。

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

引用 MSDN 作为权威来源,.NET Standard 旨在成为一个可以统辖它们的库。由于图片胜过千言万语,以下内容会很清楚:

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

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

2。 .NET 标准库将为您带来什么(跨框架兼容性)

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

对于不耐烦的人:

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

根据您打算在哪些 .NET 平台上运行,获取帮助了解您可以定位的最高 .NET Standard 版本的表格,head over here。

来源:MSDN: Introducing .NET Standard

【讨论】:

ASP.NET Core 在该图中有点错位,因为它可以与完整的 .NET Framework 一起使用,而不仅仅是 .NET Core,因为它实际上以 .NET Standard 为目标。 但是您可以使用完整的 .NET Framework 创建 ASP.NET Core 应用程序 - ASP.NET Core 确实与 .NET Standard 属于同一层。它不仅限于 .NET Core。 @Neme 首先,是的 .Net Core 可以包含 .Net Framework 库,但失去了跨平台重用(仅适用于 Windows - 不是 *nix 或 OSX,或在 Xamarin 中重用)。鉴于许多人已经并希望重用以完整.Net Framework 编写的现有库,而对跨平台优势(操作系统级别和应用程序模型级别)不感兴趣,这种情况得到了满足......如果你仍然觉得我错了,也许您可​​以与创作这些图像的微软争论...... :-) 我不是在谈论结合 .NET Core 和 .NET Framework。我的观点是 ASP.NET Core 根本不依赖于 .NET Core,尽管有这个名字。它是作为面向 .NET Standard 的库编写的,因此您可以在任何可以使用 .NET Standard 的地方使用它。是的,他们在那张图片中犯了一个错误。 @OgrishMan 您无法在 .Net Standard 中创建可执行文件。它只能是一个类库,可以被其他执行代码引用。 它没有运行时【参考方案3】:

简短的回答是:

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

【讨论】:

@Joe.wang 我认为它弄乱了 .NET Core 和 .NET Framework 之间的关系是很糟糕的。如果 .NET Core 是鸟,那么 .NET Framework 就不可能是鹰(也许猫更合适)。 @LexLi 是对的,这使水变得浑浊。 .NET Framework 不是 .NET Core 的子类型。 这可能看起来有点花哨,但并不准确 @Joe 的原始评论听起来更准确。社区编辑的答案令人困惑 狗的特征比猫多?没有:)【参考方案4】:

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

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

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

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

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

.NET Standard 在系统管理员团队出于哲学或成本原因希望从 Windows 上的 ASP.NET 迁移到 Linux 上的 .NET Core 的 ASP.NET 但开发团队希望继续的情况下也很有用在 Windows 上的 Visual Studio 中使用 .NET Framework。

【讨论】:

虽然很好地概述了 .NET Core 和 .NET Standard 是什么,但此答案无法回答有关针对它们中的每一个的类库的问题。 如果这是你的目标,那么这个问题需要以“不清楚你在问什么”来结束,因为对于我们来说,对于特定人的环境来说,总会有太多的情境细节永远只是告诉你该怎么做,或者如果你问的是一般情况,那就是“太宽泛”了。我们在这里所能做的就是为您提供有关产品的信息,以便您了解自己的决定。 显然不是这样,因为另一个人已经准确地回答了这个问题。我的问题是关于类库的。你的回答是关于框架的。【参考方案5】:

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

.NET Standard 是一种标准(换言之,一种规范)。

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

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

【讨论】:

【参考方案6】:

我希望这将有助于理解 .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

【讨论】:

【参考方案7】:

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

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

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

使用 .NET Standard,您可以使用更少的工具,但您可以针对所有/大多数平台。借助 Xamarin,您可以定位 移动,借助 Mono/Unity,您甚至可以定位 游戏机。也可以使用 UNO 平台和Blazor 来定位 Web 客户端(尽管目前两者都处于试验阶段)。

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

共享服务器和静默:

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

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

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

服务器端(Web API):

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

一个 .NET Core 项目,它处理 Rest API 并利用 数据库库。

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

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

一个处理客户端 API 连接的 .NET Standard 库。

处理 ViewModels 逻辑的 .NET Standard 库。它用于 所有的意见。

处理 WPF 视图的 .NET Framework WPF 应用程序 窗口应用程序。 WPF 应用程序现在可以是 .NET 核心,尽管它们目前只能在 Windows 上运行。 AvaloniaUI 是为其他桌面平台制作桌面 GUI 应用程序的不错选择。

一个处理 Xamarin 表单视图的 .NET Standard 库。

Xamarin Android 和 Xamarin iOS 项目。

因此您可以看到应用程序的客户端有一个很大的优势,因为我可以重用 .NET 标准库(client API 和 ViewModels)并且只创建没有逻辑的视图适用于 WPF、Xamarin 和 iOS 应用程序。

【讨论】:

我认为这是一个更好的答案,因为它结合了现实世界。【参考方案8】:

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

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

UWP 也使用它,新的 ASP.NET Core 也将它用作依赖项。

【讨论】:

【参考方案9】:

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

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

【讨论】:

【参考方案10】:

前面的答案可能描述了对 .NET Core、.NET Standard 和 .NET Framework 之间区别的最佳理解,所以我只想分享我在选择这个而不是那个时的经验。

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

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

所以我们想要构建一个可用于 .NET Core (ASP.NET Core) 和 Windows 服务和报告 (.NET Framework) 的基础架构库 -> 这就是我们为此类库选择 .NET Standard 的原因. 选择 .NET 标准意味着您需要仔细考虑库中的每个类都应该简单且跨 .NET(Core、Framework 和 Standard)。

结论:

.NET Standard 用于基础结构库和共享公用。此库可供 .NET Framework 和 .NET Core 引用。 .NET Framework 用于不受支持的技术,例如 Active Report、Window Services(现在支持 .NET 3.0)。 .NET Core 用于 ASP.NET Core。

微软刚刚发布了 .NET 5:Introducing .NET 5

【讨论】:

@Gigi 请仔细阅读我的回答,我说是在 .NET Core 1.0 版本的时候,我们想设计一个解决方案来结合 .NET Core 和 .NET 框架。 ASP.NET Core 支持 2.0 以上的 .NET Framework。我的回答是当您必须处理多个版本的 .NET 时的故事。所以我不明白为什么当你没有正确理解情况时你会投反对票。 感谢您的回答 - 我确实阅读了您的回答,并且确实阅读了您提到 .NET Core 1.0 的部分。然而,我没有将其作为解释您的结论的先决条件,否则会误导人们使用当前版本进行阅读。此外,我的评论似乎遭到了 Stack Overflow 警察的抨击,这是我在这个网站上已经习惯的一种耻辱。【参考方案11】:

.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 语言.NET

【讨论】:

【参考方案12】:

.NET 核心 .NET Core 是托管框架的免费、跨平台、开源实现。它支持四种类型的应用程序:控制台、ASP.NET Core、云和通用 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 标准 托管框架的每个实现都有自己的一组基类库。基类库 (BCL) 包含异常处理、字符串、XML、I/O、网络和集合等类。

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

WPF、WCF 和 ASP.NET 等框架类库 (FCL) 不属于 BCL,因此不包含在 .NET Standard 中。

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

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

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

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

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

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

【讨论】:

【参考方案13】:

每个框架都有自己的类库。

.Net Framework 的基类库。 .Net 核心的核心库。 Xamarin 的单一类库。

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

Microsoft 已决定制作一个统一的框架。 .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 Core 和 .NET 标准类库项目类型有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

.NET 和 .NET Core 项目的单一类库项目

.Net Core 项目类型,用于与多个项目共享布局

如何在标准类库中读取 .Net Core 配置?

如何在 .NET Core 类库中引用 Visual Studio 共享项目

无法从完整的 .NET 项目项目引用 .NET Core 类库

为什么在一个解决方案中混合.Net Standard和.Net Core项目?