Хранилище пакетов среды выполнения

Начиная с версии .NET Core 2.0, можно упаковывать и развертывать приложения на основе известного набора пакетов, имеющегося в целевой среде. Преимущества заключаются в ускорении развертывания, сокращении используемого дискового пространства и в некоторых случаях повышении производительности запуска.

Эта возможность реализована в виде хранилища пакетов среды выполнения, представляющего собой каталог на диске, в котором хранятся пакеты (как правило, /usr/local/share/dotnet/store в macOS или Linux и C:/Program Files/dotnet/store в Windows). В этом каталоге есть подкаталоги для архитектур и целевых платформ. Структура файлов аналогична структуре ресурсов 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.Json и Moq в хранилище пакетов среды выполнения.

<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. В случае с проектами с открытым кодом ситуация иная. Пользователи проекта с открытым кодом, как правило, развертывают его в разных рабочих средах. В этих рабочих средах обычно предустановлены разные наборы пакетов. Делать предположения о целевых манифестах в таких средах нельзя, поэтому следует использовать параметр --manifest команды dotnet 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. Предполагается, что эти пакеты имеются в целевой системе.

Хранилище пакетов среды выполнения устанавливается на узле при установке пакета SDK для .NET. Другие установщики также могут предоставлять хранилище пакетов среды выполнения. Сюда относятся установки пакета SDK для .NET из архива Zip или tarball, apt-get, Red Hat Yum, пакет .NET Core Windows Server Hosting и установки хранилища пакетов среды выполнения, осуществленные вручную.

При развертывании приложения с зависящим от платформы развертыванием в целевой среде должен быть установлен пакет SDK для .NET. Если приложение развертывается в среде, в которой нет ASP.NET Core, можно отказаться от неявного хранилища, указав <значение PublishWithAspNetCoreTargetManifest false> в файле проекта, как показано в следующем примере:

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

Примечание.

В случае с приложениями с автономным развертыванием предполагается, что в целевой системе необязательно имеются требуемые пакеты манифеста. <Поэтому для автономного приложения нельзя задать true значение PublishWithAspNetCoreTargetManifest>.

См. также