在Visual Studio中,至少可以创建3种不同类型的类库:
- 类库(.NET Framework)
- 类库(.NET标准)
- 类库(.NET Core)
尽管第一个是我们多年来一直在使用的东西,但我一直感到困惑的主要点是何时使用.NET Standard和.NET Core类库类型。尝试多目标化不同的框架版本并创建单元测试项目时,我最近对此颇为bit恼。
那么,类库(.NET Standard)和类库(.NET Core)有什么区别,为什么两者都存在,以及何时应在另一个之上使用?
在Visual Studio中,至少可以创建3种不同类型的类库:
尽管第一个是我们多年来一直在使用的东西,但我一直感到困惑的主要点是何时使用.NET Standard和.NET Core类库类型。尝试多目标化不同的框架版本并创建单元测试项目时,我最近对此颇为bit恼。
那么,类库(.NET Standard)和类库(.NET Core)有什么区别,为什么两者都存在,以及何时应在另一个之上使用?
Answers:
我们什么时候应该使用另一个?
决定是在兼容性和API访问之间进行权衡。
当您想增加与库兼容的应用程序的数量时,可以使用.NET Standard库,并且可以减少库可以访问的.NET API表面积。
如果要增加库可以访问的.NET API表面积,请使用.NET Core库,并且可以只允许.NET Core应用程序与库兼容。
例如,面向.NET Standard 1.3的库将与面向.NET Framework 4.6,.NET Core 1.0,Universal Windows Platform 10.0以及支持.NET Standard 1.3的任何其他平台的应用程序兼容。但是,该库将无法访问.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标准库包含所有内容,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标准库模板可以在多个运行时上运行(以API表面积为代价)。相反,.NET Core库模板的存在是为了访问更多API表面积(以兼容性为代价)并指定用于构建可执行文件的平台。
这是一个交互式矩阵,显示哪个.NET Standard支持哪个.NET实现以及可用的API表面积有多少。
一个.NET核心类库是基于内置.NET标准。如果您想实现可移植到.NET Framework的库,则。.NET Core和Xamarin,请选择.NET标准库
.NET Core最终将实现.NET Standard 2(Xamarin和.NET Framework也会如此)
.NET核心,Xamarin和.NET框架可以,因此也被认定为调味剂的.NET标准
为了使您的应用程序能够面向未来,以进行代码共享和重用,您宁愿实现.NET Standard库。
Microsoft还建议您使用.NET Standard而不是Portable Class Libraries。
为了引用MSDN作为权威来源,.NET Standard旨在成为统治一切的一个库。由于图片值一千个字,因此以下内容将使您非常清楚:
1.您当前的应用场景(碎片化)
与我们大多数人一样,您可能处于以下情况:(.NET Framework,Xamarin和现在的.NET Core风格的应用程序)
2. .NET标准库将为您提供什么(跨框架兼容性)
实施.NET标准库可实现所有这些不同类型的代码共享:
对于急躁的人:
要获得一张表格,以帮助您了解打算基于哪个.NET平台运行的.NET Standard的最高版本,请访问此处。
因此,简短的答案是:
IAnimal == .NetStandard (General)
ICat == .NetCore (Less General)
IDog == .NetFramework (Specific / oldest and has the most features)
.NET和.NET Core是.NET运行时的两种不同实现。核心和框架(但特别是框架)都有不同的配置文件,这些配置文件包含Microsoft为.NET创建的许多API和程序集的大小选择(或只是略有不同),具体取决于它们的安装位置和配置文件。
例如,通用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等也是如此。只要运行时提供对程序所针对的Standard版本的支持,程序就应在其中运行。
针对Standard版本的项目将无法使用该标准修订版中未包含的功能。这并不意味着您不能依赖于其他程序集或其他供应商发布的API(即:NuGet上的项目)。但这确实意味着,您获取的所有依赖项还必须包括对您的.NET Standard版本的支持。.NET Standard正在迅速发展,但是它仍然很新,并且对一些较小的运行时配置文件非常在意,这一限制令人感到窒息。(请注意一年半之后:这种情况已经开始改变,并且最新的.NET Standard版本更加美观,功能更强大)。
另一方面,针对Standard的应用程序应该能够在更多的部署情况下使用,因为从理论上讲,它可以与Core,Framework,Mono等一起运行。对于寻求广泛分发的类库项目,这是一个诱人的希望。对于主要用于内部目的的类库项目,它可能不会引起太大的关注。
在系统管理员团队出于哲学或成本原因而希望从Windows上的ASP.NET迁移到Linux上的.NET Core的ASP.NET的情况下,.NET Standard也很有用,但是开发团队希望继续努力。 Windows上的Visual Studio中的.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
}
}
解释差异的另一种方法可能是在现实世界中的示例,因为我们大多数人都将使用现有工具和框架(Xamarin,Unity等)来完成这项工作。
因此,使用.NET Framework,您可以使用所有.NET工具,但只能针对Windows应用程序(UWP,Winforms,ASP.NET等)。由于.NET Framework是封闭源代码,因此无需太多处理。
使用.NET Core,您拥有较少的工具,但是您可以针对主要的桌面平台(Windows,Linux,Mac)。这在ASP.NET Core应用程序中特别有用,因为您现在可以在Linux中托管Asp.net(更便宜的托管价格)。现在,由于.NET Core是开源的,因此在技术上可以为其他平台开发库。但是由于没有支持它的框架,所以我认为这不是一个好主意。
使用.NET Standard,您拥有甚至更少的工具,但您可以针对所有/大多数平台。您可以通过Xamarin来定位Mobile,甚至可以通过Mono / Unity来定位游戏机。更新:也可以使用UNO平台和Blazor来定位Web客户端(尽管两者目前都处于试验阶段)。
在实际的应用程序中,您可能需要使用所有这些。例如,我开发了具有以下架构的销售点应用程序:
共享服务器和客户端:
由于它是.NET标准库,因此可以在任何其他项目(客户端和服务器)中使用。
在.NET标准库上进行验证也是一个很好的优点,因为我可以确保在服务器和客户端上应用相同的验证。服务器是必需的,而客户端是可选的,对减少流量很有用。
服务器端(Web API):
处理所有数据库连接的.NET Standard(也可以是Core)库。
一个处理Rest API并使用数据库库的.NET Core项目。
由于它是在.NET Core中开发的,因此我可以将应用程序托管在Linux服务器上。
客户端(带有WPF + Xamarin.Forms Android / IOS的MVVM):
一个处理客户端API连接的.NET Standard库。
一个处理ViewModels逻辑的.NET标准库。在所有视图中使用。
.NET Framework WPF应用程序,用于处理Windows应用程序的WPF视图。更新:WPF应用程序现在可以是.NET核心,尽管它们目前仅在Windows上运行。AvaloniaUI是为其他桌面平台制作桌面GUI应用程序的不错选择。
一个处理Xamarin Forms视图的.NET标准库。
Xamarin Android和Xamarin IOS项目。
因此,您可以看到应用程序的客户端具有很大的优势,因为我可以重用.NET标准库(客户端API和ViewModels),并且只需为WPF,Xamarin和IOS应用程序创建没有逻辑的视图。
.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 +桌面特定的东西。
上面的答案可能描述了有关网络核心,网络标准和网络框架之间差异的最佳理解,因此我只想分享我的经验。
在项目中,您需要在.NET Framework,.NET Core和.NET Standard之间混合使用。例如,当我们使用.NET Core 1.0构建系统时,不支持使用.net Core的Window Services托管。
下一个原因是我们使用了不支持.NET Core的Active Report。因此,我们要构建一个可同时用于.NET Core(asp.net核心)和Windows Service and Reporting(.NET Framework)的基础结构库,这就是为什么我们选择.NET Standard作为此类库的原因。选择.NET标准意味着您需要仔细考虑库中的每个类都应该是简单的并且跨.NET(核心,框架,标准)。
结论:
微软刚刚宣布.NET 5:https://devblogs.microsoft.com/dotnet/introducing-net-5/
.NET Framework Windows窗体,ASP.NET和WPF应用程序必须使用.NET Framework库进行开发
.NET标准 Xamarin,IO和MAC OSx应用程序必须使用.NET标准库进行开发
.NET Core
通用Windows平台(UWP)和Linux应用程序必须使用.NET Core库进行开发。该API以C ++实现,您可以使用C ++,VB.NET,C#,F#和Javascript语言。