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

类库(。净框架) 类库(。净标准) 类库(。净核心)

虽然第一种是我们已经使用多年的,但我一直困惑的一个主要问题是什么时候使用. net Standard和. net Core类库类型。最近当我尝试多目标不同的框架版本,并创建一个单元测试项目时,我就被这个问题咬了一口。

那么,类库(。NET标准)和类库(。NET Core),为什么两者都存在,什么时候我们应该使用其中一个而不是另一个?


当前回答

简短的回答是:

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

其他回答

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

因此,有了。net框架,你可以使用所有的。net工具,但你只能针对Windows应用程序(UWP, Windows窗体,ASP。网,等等)。由于. net框架是闭源的,所以没有太多的事情可以做。

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

使用. net Standard,你的工具就更少了,但是你可以针对所有/大多数平台。因为Xamarin,你可以瞄准手机,因为Mono/Unity,你甚至可以瞄准游戏机。也可以通过UNO平台和Blazor来定位web客户端(尽管目前两者都处于实验阶段)。

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

同时共享server和silent:

处理应用程序模型的. net标准库。 一个. net标准库,用于处理客户端发送的数据的验证。

由于它是一个。net标准库,它可以用于任何其他项目(客户端和服务器)。

在. net标准库上进行验证还有一个很好的优点,因为我可以确保在服务器和客户端上应用相同的验证。服务器是必须的,而客户端是可选的,有助于减少流量。

服务器端(Web API):

处理所有数据库连接的。net Standard(也可以是。net Core)库。 处理Rest API并使用。net Core项目 图书馆数据库。

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

客户端(MVVM与WPF + Xamarin。Android / iOS形式):

A .NET Standard library that handles the client API connection. A .NET Standard library that handles the ViewModels logic. It is used in all the views. A .NET Framework WPF application that handles the WPF views for a windows application. WPF applications can be .NET core now, although they only work on Windows currently. AvaloniaUI is a good alternative for making desktop GUI applications for other desktop platforms. A .NET Standard library that handles Xamarin forms views. A Xamarin Android and Xamarin iOS project.

所以你可以看到在应用程序的客户端有一个很大的优势,因为我可以重用。net标准库(客户端API和ViewModels),并且只为WPF、Xamarin和iOS应用程序创建不带逻辑的视图。

我希望这将有助于理解。net标准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
    }

}

前面的回答可能描述了关于。net Core、。net Standard和。net Framework之间区别的最好理解,所以我只想分享一下我在选择这个而不是那个时的经验。

在项目中,你需要混合。net框架,。net核心和。net标准。例如,当我们用。net Core 1.0构建系统时,。net Core还不支持windows服务托管。

第二个原因是我们使用的是不支持。net Core的活动报表。

因此,我们想要构建一个基础架构库,它可以用于。net Core (ASP。NET Core)和Windows服务和报告(。这就是为什么我们选择。NET Standard作为这类库的原因。 选择。net标准意味着你需要仔细考虑库中的每个类都应该是简单的,并且跨越。net(核心、框架和标准)。

结论:

. net标准的基础架构库和共享公共。这个库可以被. net Framework和. net Core引用。 . net框架不支持的技术,如活动报告,窗口服务(现在支持。net 3.0)。 . net核心的ASP。当然是NET Core。

微软刚刚宣布了。net 5:引入。net 5

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

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

当你想要增加与你的库兼容的应用程序的数量,并且你可以接受你的库可以访问的。net API表面积的减少时,使用。net标准库。

当你想要增加你的库可以访问的。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标准)和类库(。网络核心)?

兼容性:以。net标准为目标的库可以在任何。net标准兼容的运行时上运行,比如。net Core、。net Framework、Mono/Xamarin。另一方面,以。net Core为目标的库只能在。net Core运行时上运行。

. NETStandard库包含了NETStandard中的所有东西。而. net Core库则包含了Microsoft.NETCore.App中的所有东西。后者包括大约20个额外的库,其中一些我们可以手动添加到。net标准库(如System.Threading.Thread),而另一些则与。net标准不兼容(如Microsoft.NETCore.CoreCLR)。

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

为什么两者都存在?

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

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

下面是一个交互式矩阵,显示了。net标准支持哪些。net实现,以及有多少可用的API表面积。

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

. net框架的基类库。 . net Core的核心库。 Xamarin的Mono类库。

微软决定将所有这些类库合并到一个可以在所有框架中实现的库中。为此,他们开发了。net标准。

微软决定做一个统一的框架,. net 5是。net核心和。net框架的统一框架。在。net 6中,他们也将Xamarin合并到。net MAUI项目中。

. net Framework, . net Core, Xamarin被统一为一个。net 6框架,所以不需要。net标准。. net标准的目标是拥有一个能在所有框架中工作的库。现在所有的框架都合并到了。net 6中。