运行时包存储区

从 .NET Core 2.0 开始,可以针对目标环境中存在的一组已知包打包和部署应用。 在某些情况下,部署速度更快、磁盘空间使用率降低和启动性能提高。

此功能作为 运行时包存储实现,它是存储包的磁盘上的目录(通常位于 macOS/Linux 上的 /usr/local/share/dotnet/store 和 Windows 上的 C:/Program Files/dotnet/store )。 在此目录下,有体系结构和 目标框架的子目录。 文件布局类似于 NuGet 资产在磁盘上布局的方式:

\dotnet
    \store
        \x64
            \netcoreapp2.0
                \microsoft.applicationinsights
                \microsoft.aspnetcore
                ...
        \x86
            \netcoreapp2.0
                \microsoft.applicationinsights
                \microsoft.aspnetcore
                ...

目标清单文件列出了运行时包存储中的包。 开发人员可以在发布他们的应用程序时以此清单为目标。 目标清单通常由目标生产环境的所有者提供。

准备运行时环境

运行时环境的管理员可以通过生成运行时包存储和相应的目标清单来优化应用,以便更快地部署和降低磁盘空间使用。

第一步是创建一个 包存储清单 ,该清单列出了构成运行时包存储的包。 此文件格式与项目文件格式(csproj)兼容。

<Project Sdk="Microsoft.NET.Sdk">
  <ItemGroup>
    <PackageReference Include="NUGET_PACKAGE" Version="VERSION" />
    <!-- Include additional packages here -->
  </ItemGroup>
</Project>

示例

以下示例包存储清单(packages.csproj)用于添加 Newtonsoft.JsonMoq 添加到运行时包存储:

<Project Sdk="Microsoft.NET.Sdk">
  <ItemGroup>
    <PackageReference Include="Newtonsoft.Json" Version="10.0.3" />
    <PackageReference Include="Moq" Version="4.7.63" />
  </ItemGroup>
</Project>

使用运行时包存储清单、运行时和框架,执行 dotnet store 来配置运行时包存储:

dotnet store --manifest <PATH_TO_MANIFEST_FILE> --runtime <RUNTIME_IDENTIFIER> --framework <FRAMEWORK>

示例

dotnet store --manifest packages.csproj --runtime win-x64 --framework netcoreapp2.0 --framework-version 2.0.0

可以通过在命令中重复选项和路径,将多个目标包存储清单路径传递到单个 dotnet store 命令。

默认情况下,命令的输出是用户配置文件的 .dotnet/store 子目录下的包存储。 可以使用该选项指定其他位置 --output <OUTPUT_DIRECTORY> 。 存储的根目录包含目标清单 artifact.xml 文件。 此文件可用于下载,并且供想要在发布时面向此应用商店的应用作者使用。

示例

运行前面的示例后,将生成以下 artifact.xml 文件。 请注意, Castle.Core 这是一个依赖项 Moq,因此它会自动包含在 artifacts.xml 清单文件中。

<StoreArtifacts>
  <Package Id="Newtonsoft.Json" Version="10.0.3" />
  <Package Id="Castle.Core" Version="4.1.0" />
  <Package Id="Moq" Version="4.7.63" />
</StoreArtifacts>

根据目标清单发布应用程序

如果磁盘上有目标清单文件,请在使用 dotnet publish 命令发布应用时指定该文件的路径:

dotnet publish --manifest <PATH_TO_MANIFEST_FILE>

示例

dotnet publish --manifest manifest.xml

将生成的已发布应用部署到具有目标清单中所述包的环境。 未能执行此作会导致应用无法启动。

通过重复选项和路径(例如, --manifest manifest1.xml --manifest manifest2.xml)在发布应用时指定多个目标清单。 这样,应用程序会进行剪裁,依据为提供给命令的目标清单文件中指定的包并集。

如果部署的应用程序具有部署中存在的清单依赖项(程序集存在于 bin 文件夹中),则运行时包存储不会在该程序集的主机上 使用 。 无论主机上的运行时包存储中是否存在,bin 文件夹程序集都会被使用。

清单中指示的依赖项的版本必须与运行时包存储中的依赖项版本匹配。 如果目标清单中的依赖项与运行时包存储中存在的版本之间存在版本不匹配,并且应用在其部署中不包括包的必需版本,则应用无法启动。 异常信息包括了调用运行时包存储程序集的目标清单的名称,这有助于排查不匹配问题。

如果在发布时部署发生剪裁,只有指明的特定版本清单包,才不会出现在已发布的输出中。 指示的版本上的包必须存在于主机上,才能启动应用。

在项目文件中指定目标清单

可以使用另一种方法替代用dotnet publish命令指定目标清单,在项目文件中,将其作为分号分隔的路径列表指定在<TargetManifestFiles>标记下。

<PropertyGroup>
  <TargetManifestFiles>manifest1.xml;manifest2.xml</TargetManifestFiles>
</PropertyGroup>

仅在应用的目标环境已知(例如 .NET Core 项目)时才在项目文件中指定目标清单。 对于开源项目,情况并非如此。 开源项目的用户通常将其部署到不同的生产环境。 这些生产环境通常预安装了不同的包集。 在这样的环境中,不能对目标清单作出假设,所以应使用 --manifestdotnet publish 选项。

ASP.NET Core 隐式存储(仅限 .NET Core 2.0)

ASP.NET Core 隐式存储仅适用于 ASP.NET Core 2.0。 强烈建议应用程序使用 ASP.NET Core 2.1 及更高版本, 而不使用隐 式存储。 ASP.NET Core 2.1 及更高版本使用共享框架。

对于 .NET Core 2.0,当应用部署为 依赖于框架的部署 应用时,ASP.NET Core 应用隐式使用运行时包存储功能。 Microsoft.NET.Sdk.Web 中的目标包括引用目标系统上的隐式包存储区的清单。 此外,依赖 Microsoft.AspNetCore.All 包的任何框架相关应用都会导致已发布应用仅包含应用及其资产,而不会包含元包 Microsoft.AspNetCore.All 中列出的包。 假定这些包存在于目标系统上。

安装 .NET SDK 时,运行时包存储安装在主机上。 其他安装程序可以提供运行时包存储,包括 .NET SDK 的 Zip/tarball 安装、 apt-getRed Hat Yum、.NET Core Windows Server 托管捆绑包和手动运行时包存储安装。

部署 依赖于框架的部署 应用时,请确保目标环境已安装 .NET SDK。 如果应用部署到不包含 ASP.NET Core 的环境,可以通过在项目文件中指定 <PublishWithAspNetCoreTargetManifest> 设置为不使用隐式存储,如以下示例所示:false

<PropertyGroup>
  <PublishWithAspNetCoreTargetManifest>false</PublishWithAspNetCoreTargetManifest>
</PropertyGroup>

注释

对于 自包含部署 应用,假定目标系统不一定包含所需的清单包。 因此,无法将 <PublishWithAspNetCoreTargetManifest> 设置为 true,因为这不适用于自包含应用。

另请参阅