乘风破浪,遇见最佳跨平台跨终端框架.Net Core/.Net生态 - 工作负载(Workload),全面统一.Net面向工作负载的部署

什么是工作负载(Workload)

https://github.com/dotnet/designs/blob/main/accepted/2020/workloads/workloads.md

image

.NET可选SDK工作负载

在.NET 5.0中,我们将增加对iOS、Android和Web Assembly项目的支持。在.NET 5.0之前,我们一直通过一个单一的SDK来提供所有支持的工作负载。随着.NET SDK支持的工作负载的增加(我们也希望如此),提供一个 "一体化/一刀切 "的SDK发行版已不再可行了。大型单体SDK面临许多挑战,其中最重要的是产品构建时间和发行规模。相反,所有新的工作负载将与SDK分开构建和交付,并且可以通过你最喜欢的安装工具(如Visual Studio安装器、Linux软件包管理器或.NET CLI)获得。随着时间的推移,我们打算让所有的.NET工作负载都遵循这种模式,从而形成一个非常小而集中的SDK

虽然单一的SDK模式已经成为一种负担,但它是.NET核心2.x和3.x的一个重要设计点。这种方法使我们能够提供SDK的两个关键价值主张:提供一套连贯的测试工作负载(这减少了我们的测试矩阵/负担),并实现离线场景(dotnet new + dotnet run默认工作--用于盒子里的模板--没有互联网)。展望未来,保留这些价值是很重要的,即使我们转向一个根本不同的SDK组成模式

作为.NET Core 3.1的一部分,我们启用了.NET的源代码构建(source build)。从.NET核心项目的一开始,我们就想让开源社区能够对.NET源代码进行 "任何操作",并让发行商能够将.NET(通过他们自己的构建机制和策略)纳入他们的包存档。我们现在看到的第一个迹象是,发行版维护者将利用.NET源码构建的优势,现在它已经发挥作用。至关重要的是,.NET源码构建功能应扩展到包括新的可选工作负载模型,以便社区能够为他们的方案构建所有的工作负载。事实上,我们希望有了这个模型,源码构建将变得更简单、更高效

本建议旨在针对作为目标框架的一部分或与之直接相关的组件,如Xamarin或Windows Forms,以及与之相关的构建工具。它并不打算用于更高层次的库。然而,一些更高级别的库可能会从类似的组合和获取经验中受益。如果有意义且可能的话,我们会随着时间的推移为高级库提供类似的功能。

详细设计

本文件是一个概述。下面的文件详细介绍了具体的设计主题。

目标

本提案的目标如下。

  • 用户可以下载他们需要的工作负载(比如只下载ASP.NET Core,或只下载Xamarin,或同时下载)。
  • 很容易为CI/CD服务器等环境配置下载一组最小的文件(仅构建组件),以限制使用的资源(线程成本、计算(用于解压)和磁盘I/O)。
  • 当开发人员在构建项目时缺少工作负载时,构建错误是很直观的,也很有帮助
  • 可以以项目文件的形式安装工作负载,这是一种 "工作负载还原",这样用户就不需要写脚本来发现所需的特定工作负载。这对GitHub Actions这样的服务来说至关重要。
  • 用户可以更新工作负载,而不一定需要安装较新版本的SDK。这包括得到工作负载更新的通知。
  • 用户可以通过任何支持的安装工具,如VS安装器、Linux软件包管理器或CLI(安装器之间的交互将在后面介绍),为SDK安装工作负载并与之互动

高级别的方法

该建议可分为两个主要议题:获取(Acquisition)组成(Composition)

  • 获取(Acquisition) 描述了通过安装工具部分或全部获取工作负载的能力和机制。
  • 组成(Composition) 描述了文件格式、数据包类型、磁盘上的位置,以及其他定义工作负载、其组成部分和相关版本的机制,这使得这些部分可以被获取、更新,并作为一个连贯的集合使用。

到目前为止,这两个主题都是由单体SDK满足的,鉴于计划增加新的、可选择的工作负载,需要重新考虑。下面几节将讨论一种新的构成和获取方法。

.NET Core 1.x的关键学习是,.NET平台需要一个独立的版本模型,而不是为NuGet库包提供的模型。一个例子是,你可以在项目中更新一个单一的目标框架值,从netcoreapp 2.1到netcoreapp 3.1,以自动更新所有依赖的平台组件(如ASP.NET Core)。使用单一的平台版本使得更新项目变得很容易,并导致一个稳定的配置,(在大多数情况下)不受软件包引用的影响。

这意味着可选的组件将不会作为NuGet包暴露出来,这些包需要项目文件中的包引用,或与包恢复一起获得或参与包恢复。相反,我们将开发一个新的系统,它是SDK组成系统的一个演变。简而言之,我们将把物理上的单体SDK演变成逻辑上的单体。这种方法将使我们能够在.NET 5中提供与.NET Core 3.1 SDK精神相似的SDK用户体验,同时承认在功能上有一些退步(你不会默认得到厨房和水槽)。

自从第一个.NET Core发布以来,我们已经在NuGet feeds上提供了各种类型的 "包 "作为专门的包1.x和2.x时代的例子3.x+时代的例子(未列出))。我们使用NuGet来实现这一目的,因为许多工具和服务都能理解NuGet包,它包括一个feeds的概念(可以是私有的或公共的),并提供一个全球CDN(就NuGet.org而言)。然而,这些包并不打算被项目文件直接引用,而是作为一个实现细节为.NET核心SDK所知。我们打算让工作负载遵循类似的模式,不同的是,.NET SDK不会有详细的包的内置知识,工作负载将从SDK中单独获得和更新

组成(Composition)

工作负载(Workload)将被组成并作为一组包分发。包只是一组压缩的文件,就像ASP.NET Core运行时。它们本身是无法被发现的,也没有描述其他可能与之合作或需要的包,或者可以使用的各种场景。包可以包括运行时、模板、MSBuild任务、工具,以及其他任何构建和运行项目所需的东西

如今,SDK中的MSBuild目标中有许多硬编码的版本和包被用来组成产品。

今后,我们将把这些组成信息外化为一组工作负载清单文件。每个工作负载将由一个清单(manifest) 来定义(可能作为其自身的小包分发),并使用它来描述其提供的版本包集。MSBuild和潜在的其他工具将被更新,以发现和读取这些清单,最终在构建和任何其他相关操作中尊重它们。

目标框架(Target Framework) 将被用作项目文件中的主要货币,这些文件建立了与工作负载的联系。作为相关工作的一部分,目标框架正在.NET 5中被更新,以包括操作系统信息。这一变化将使我们能够直接链接到操作系统特定的工作负载。例如,一个以net5.0-android为目标的项目将需要.NET 5 Android工作负载(Xamarin.Android)。一个针对net5.0-androidnet5.0-ios的项目也需要.NET 5 iOS工作负载(Xamarin.iOS)。

工作负载(Workload) 所定义的TFM到工作负载的映射集。SDK将携带该映射的副本,但当工作负载呈现较新的信息时,将服从于作为已安装工作负载的一部分所携带的信息。

每个工作负载将提供一组用户可以使用的软件包。这些包中的一个将是你得到的满足TFM的默认包。额外的捆绑包将提供额外的功能。例如,Android AOT支持将作为一个额外的捆绑包暴露出来,而不是由默认的捆绑包提供。这些额外的捆绑包可以作为项目属性被引用为项目的必要依赖,或者通过CLI或支持的安装工具手动安装。

获取(Acquisition)

工作负载(Workload) 将通过两种主要方式获得:通过支持的安装工具.NET CLI

注意:"支持的安装工具"这一术语旨在描述一个公开组件并管理其依赖关系的安装系统。例如,Visual Studio Installer、Docker和APT就是这样做的,而MSI和PKG不是这样。

安装工具对其安装的工作负载必须遵循这些规则:

  • 工作负载清单(workload manifest)作为工作负载的所有变体的必要依赖项被包括在内(有些包可能是可选的)。
  • 所有引用的软件包都包括在内,与工作负载清单中指定的版本相匹配。

不安装清单或不安装清单要求的所有文件的安装工具将创建未定义的环境,为用户产生未定义的结果。也许可以在.NET工具中检测到这些错误情况,并向用户提供适当的反馈,但很可能不是在所有情况下。

组合模型(compositional model) 可以说是脆弱的。我们可能需要公开一个CLI命令来验证.NET核心的安装/环境,以便产生一个可以检查和共享的详细日志。

.NET CLI将提供一套更广泛的命令来与工作负载进行互动。CLI可能会允许安装更多的工作负载,这样它所暴露的名词就不是工作负载,而是更普遍的东西(待定;在下面的例子中,bundle被用作更好的术语的替身)。在这种说法中,工作负载是bundle的一种。

  • dotnet bundle install [bundle] -- 按名称安装一个bundle。
  • dotnet bundle restore [project] -- 根据在一个或多个引用的项目中发现的依赖工作负载来安装一个或多个工作负载。我们可以认为restore是为一个工作负载安装默认的bundle。该工作负载可能会暴露出其他选择的捆绑程序。
  • dotnet bundle update [bundle | project] -- 更新一个bundle,以项目的名义,或者作为更新所有已知bundle的一部分。

我们不打算让基于.NET CLI的安装与软件包工具(如APT或Yum)进行混合搭配。相反,我们在想,一个安装工具会提供一个映射文件,将其软件包映射到工作负载,这样dotnet bundle restore就可以提供有意义的错误信息,引导用户通过安装工具安装工作负载。我们仍然需要花更多的时间来定义.NET CLI和安装工具之间的互动关系

工作负载将是可更新的。SDK将包括一种机制,以发现工作负载清单包是否已经更新。更新的清单可以代表错误修复或新功能(如操作系统更新的绑定)。如果清单已被更新,用户将得到通知,并有机会获得新版本。更新将不会是自动的。这大致上类似于Debian软件包管理器apt-get update apt-get upgrade的组合。

SDK和工作负载版本化

现有的单片式SDK的另一个好处是,它所包含的工作负载已知与SDK的核心组件(如C#编译器、NuGet、MSBuild和SDK目标)兼容。随着时间的推移,我们已经形成了SDK功能带的概念。这些功能带由SDK的数百个版本代表,如3.1.1003.1.200。这些特征带与Visual Studio版本一致,如16.416.5。我们这样做是因为这些相同的核心SDK组件在Visual Studio和.NET SDK之间共享。此外,这些组件的新的主要版本,可能包含一个新的语言版本,可以在功能段中交付。我们预计,工作负载清单(可能还有实际的工作负载)将需要为每个SDK功能段重新发布

时间安排(Timing)

这个项目有一个非常大的范围,需要改变多个大型软件的工作方式。我们正计划以下列多版本的进度来分阶段进行工作。

.NET 5.0

  • 定义清单格式和包装。
  • 启用Xamarin和Web Assembly作为工作负载。
  • 只通过Visual Studio(Windows和Mac)分发这些工作负载。
  • 如果有的话,为收购而公开的.NET CLI动词很少。

.NET 6.0以上

  • 暴露全部的.NET CLI动词供获取。
  • 将WPF、Windows Forms和ASP.NET Core作为工作负载分离出来/公开。
  • 通过.NET CLI实现所有工作负载的获取,并至少通过Linux软件包管理器提供ASP.NET Core和Web Assembly工作负载。
  • 定义并实现与安装工具的互动。

实战参考

">= .NET 6 SDK"

列出已安装的工作负载-"workload list"

dotnet workload list

image

dotnet workload search

image

dotnet workload search $keyword

例如:

dotnet workload search maui

image

安装可选的工作负载-"workload install"

dotnet workload install $workloadId

image

例如:

dotnet workload install maui-desktop

image

dotnet workload install maui

image

一口气安装多个工作负载。

dotnet workload install $workloadId $workloadId

例如:

dotnet workload install maui-android maui-windows

image

卸载指定的工作负载-"workload uninstall"

dotnet workload uninstall $workloadId

例如:

dotnet workload uninstall maui-windows

image

更新已安装的工作负载-"workload update"

dotnet workload repair

image

修复工作负载安装-"workload repair"

dotnet workload repair

image

安装项目或解决方案所需的工作负载-"workload restore"

dotnet workload restore
dotnet workload restore $project.csproj

试试通过工作负载的模板来创建项目

dotnet new maui -o demoForMaui

image

image

参考

posted @ 2022-03-02 17:16  TaylorShi  阅读(546)  评论(0编辑  收藏  举报