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

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

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

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


当前回答

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 Update。由于. net Core运行时是App-Local安装的,并且应用程序是通过包管理器更新的,因此应用程序可以与特定的. net Core版本相关联并单独更新。

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

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

框架类库(FCL),如WPF, WCF和ASP。NET不是BCL的一部分,因此不包括在。NET标准中。

. net标准和. net实现之间的关系就像HTML规范和浏览器之间的关系一样。第二个是第一个的实现。

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

每个. net版本都有一个。net标准的相关版本。

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

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

您还可以为平台特定的api构建. net标准包装器。

其他回答

我希望这将有助于理解。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标准的存在主要是为了改进代码共享,并使每个. net实现中可用的api更加一致。

在创建库时,我们可以将目标设置为。net Standard 2.0,这样所创建的库就可以兼容不同版本的。net Framework,包括。net Core、Mono等等。

. net和. net Core是. net运行时的两种不同实现。Core和Framework(尤其是Framework)都有不同的配置文件,包括微软为. net创建的许多api和程序集的或大或小(或只是完全不同)的选择,这取决于它们安装在什么配置文件中。

例如,与“普通”Windows配置文件相比,通用Windows应用程序中有一些不同的api。即使在Windows上,你也可能有“Client”配置文件和“Full”配置文件。此外,还有其他实现(如Mono)有自己的库集。

. net Standard是一种必须提供API库和程序集集的规范。一个为。net Standard 1.0编写的应用程序应该能够编译和运行任何版本的Framework、Core、Mono等,只要它宣称支持。net Standard 1.0的库集合。类似的情况也适用于。net标准1.1、1.5、1.6、2.0等。只要运行时提供了对您的程序所针对的标准版本的支持,您的程序就应该在那里运行。

A project targeted at a version of Standard will not be able to make use of features that are not included in that revision of the standard. This doesn't mean you can't take dependencies on other assemblies, or APIs published by other vendors (i.e.: items on NuGet). But it does mean that any dependencies you take must also include support for your version of .NET Standard. .NET Standard is evolving quickly, but it's still new enough, and cares enough about some of the smaller runtime profiles, that this limitation can feel stifling. (Note a year and a half later: this is starting to change, and recent .NET Standard versions are much nicer and more full-featured).

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

. net标准在系统管理员团队想要从ASP。NET在Windows到ASP。出于哲学上或成本上的原因,NET用于Linux上的。NET核心,但开发团队希望继续在Windows上的Visual Studio中使用。NET框架。

. net Standard:可以把它看作一个大的标准库。当将此作为依赖项使用时,您只能生成库(. dll),而不能生成可执行文件。用. net标准创建的库可以作为依赖项添加到Xamarin中。安卓,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也将其作为依赖项使用。

前面的回答可能描述了关于。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