Andriy Shyrokoryadov

.Net developer, data scientist

№5 Хост приложения Asp.Net Core [#55].

Текст к видео "Хост приложения Asp.Net Core" на канале YouTube

Всем привет. Тема сегодняшнего видео - хост приложения в ASP.NET Core Каждое приложение Asp.Net Core имеет свой хост. Хост – это некоторый объект, который содержит в себе ресурсы приложения. К таким ресурсам можно отнести:

  • имплементации интерфейса IHostedService, который определяет 2 метода для управления объектами хостом, метод для старта приложения и метод для завершения работы приложения.
  • фреймворк для логирования - встроенный в ASP.NET Core или созданный сторонними компаниями
  • фреймворк для внедрения зависимостей - встроенный в ASP.NET Core или созданный сторонними компаниями
  • конфигурация приложения

Если вас спросят, какая была цель объединения всех этих ресурсов в одном приложении, то необходимо отметить, что речь идет об упрощенном управлении жизненным циклом приложения: управление стартом приложения и правильным прекращением его работы.

Когда хост начинает свою работу, он вызывает метод StartAsync интерфейса IHostedService на каждой реализации данного интерфейса, которая была зарегистрирована в хосте. В случае веб-приложения одной из реализаций интерфейса IHostedService является веб услуга, которая запускает HTTP сервер.

Для того, чтобы использовать хост его необходимо настроить, построить и запустить. Как правило это происходит в методе Main класса Programm. В этом методе выполняются 3 операции: создается и настраивается объект строителя, который имплементирует интерфейс IHostBuilder; далее на данном объекте вызывается метод Build, то есть мы строим хост; после, так называемой постройки, мы запускаем хост, вызывая метод Run.

Мы можем настроить хост, чтобы он запускался как веб приложение. В этом случае в методе CreateHostBuilder мы вызываем метод ConfigureWebHostDefaults. Но это не единственная возможность. Мы можем запустить приложение ASP.NET Core с классом, который выполняет какую-то определенную бизнес-логику, но никак не связан с веб сервером, запросами и веб услугами. Для этого хост необходимо построить с вызовом метода

ConfigureServices((hostContext, services) =>
	{
		services.AddHostedService<Worker>();
	});

В этом случае класс Worker должен реализовывать интерфейс IHostedService.

Во время создания нового приложения ASP.NET Core для постройки хоста в шаблоне добавляются 2 метода: CreateDefaultBuilder и ConfigureWebHostDefaults. Слово Default в названии этих двух методов, которое означает «по умолчанию», нам подсказывает, что эти 2 метода используются для постройки хоста с настройками по умолчанию. Давайте попробуем разобраться какие настройки хоста являются настройками по умолчанию.

Метод CreateDefaultBuilder выполняет следующие действия:

  • устанавливает папку с содержимым приложения на текущую папку приложения;
  • загружает настройки хоста из переменных среды, которые начинаются со строки DOTNET_ и аргументы командной строки;
  • загружает настройки приложения из файлов appsettings.json, переменных среды, аргументов командной строки. Если приложение запущено в среде разработки (например, компьютер программиста), то также подгружается также информация с ограниченным доступом, которая касается программиста – пользователя данного приложения.
  • добавляются некоторые поставщики логирования приложения;
  • добавляются некоторые дополнительные проверки, если приложение запущено в среде разработки (например, компьютер программиста).

Метод ConfigureWebHostDefaults выполняет следующие действия:

  • загружает настройки хоста из переменных среды, которые начинаются со строки ASPNETCORE_;
  • устанавливает сервер Kestrel в качестве веб-сервера и настраивает его, используя конфигурацию хостинга, которая содержится во всех доступных источниках конфигурации приложения.
  • добавляет связующий программный компоненты для фильтрования хостов;
  • добавляет связующий программный компонент для пересылки заголовков если переменная среды ASPNETCORE_FORWARDEDHEADERS_ENABLED имеет значение true;
  • включает интеграцию с сервером IIS.

Существует несколько услуг, которые регистрируются фреймворком ASP.NET Core при запуске приложения автоматически:

  • IHostApplicationLifetime
  • IHostLifetime
  • IHostEnvironment / IWebHostEnvironment

Услугу IHostApplicationLifetime можно внедрить в любой класс через конструктор данного класса и подписавшись на свойства данной услуги связанные со стартом приложения, остановкой приложения и полной остановкой приложения можно выполнить в текущем классе определенные действия на конкретных этапах работы приложения. Например, что-то инициализировать при старте приложения или наоборот корректно освободить ресурсы приложения при прекращении его работы. Стоит также отметить, что услуга IHostApplicationLifetime имеет также метод для прекращения работы приложения.

Услуга IHostLifetime содержит 2 метода StopAsync и WaitForStartAsync. Я признаюсь не часто пользовался интерфейсом, а если сказать точнее, то вообще им не пользовался. Но я могу сказать, что второй метод WaitForStartAsync используется для отложенного старта приложения – можно отложить старт приложения до наступления определенного события извне.

При помощи услуги IHostEnvironment можно получить информацию о названии приложения, текущей среде приложения и путь к папке с содержимым приложения. Если речь идет об услуге IWebHostEnvironment, то она наследует IHostEnvironment и добавляет еще одно свойство WebRootPath, где можно найти пусть к папке с веб содержимым, речь идет о папке wwwroot.

Конфигурация хоста используется для настройки свойств в классе, которые реализует интерфейс IHostEnvironment. Чтобы добавить конфигурацию хоста, необходимо добавить вызов метода ConfigureHostConfiguration. Этот метод может быть вызван несколько раз и общий результат данных нескольких вызовов будет суммой всех результатов. Если в течение нескольких вызовов одна настройка была установлена несколько раз, то будет использоваться та настройка, которая была настроена последней. В данном методе мы можем выполнить следующие операции:

  • установить папку с содержимым приложения, используя метод SetBasePath
  • добавить файл Json с конфигурацией приложения, используя метод AddJsonFile
  • добавить чтения переменных среды с определенным префиксом, используя метод AddEnvironmentVariables
  • добавить аргументы командной строки, используя метод AddCommandLine

Если мы настраиваем не веб приложения, а например консольное приложение ASP.Net Core, которое не будет обслуживать запросы HTTP, то вместо метода ConfigureHostConfiguration, можно вызвать метод ConfigureAppConfiguration, который работает аналогично методу ConfigureHostConfiguration.

При настройке хоста все опции настроек можно поделить на 3 группы:

  • настройки, которые применимым для всех типов приложений: как для приложений, обслуживающих запросы HTTP, так для приложений, которые такие запросы не обслуживают;
  • настройки исключительно для приложений, обслуживающих запросы HTTP – веб приложения;
  • настройки исключительно для приложений, которые не обслуживающих запросы HTTP;

Общие настройки для обоих типов приложений:

  • ApplicationName – название сборки, в которой находится точка входа в приложение. Для установки этой опции необходимо использовать переменную среды, которое называется **APPLICATIONNAME**. Здесь PREFIX – это какая-то уникальная строка, по которой будут загружаться переменные среды при помощи метода AddEnvironmentVariables.
  • ContentRoot – папка, которой находится содержимое приложения. Эту опцию можно настроить либо при помощи переменной среды **CONTENTROOT** или используя метод UseContentRoot на объекте IHostBuilder.
  • EnvironmentName – это определитель нашей среды. Фреймворк ASP.NET Core предопределяет 3 значения, которые могут быть записаны, как большими, так и маленькими буквами: Development, Staging и Production. Эту опцию можно настроить либо при помощи переменной среды ** ENVIRONMENT** или используя метод UseEnvironment на объекте IHostBuilder.
  • ShutdownTimeout – эта опция определяет таймоут на выключение приложения, а точнее она определяет таймаут для метода StopAsync, который определён в реализациях интерфейса IHostLifetime. Эта опция имеет значение по умолчанию – 5 секунд. Эту опцию можно настроить либо при помощи переменной среды ** SHUTDOWNTIMEOUTSECONDS** либо присвоив определенное значение свойству в объекте HostOptions.
  • В приложениях ASP.NET Core если файл JSON с настройками изменить во время работы приложения, то настройки будут автоматически загружены. Возможно такая функциональность не всегда желательна и её можно отключить, используя опцию hostBuilder:reloadConfigOnChange. По умолчанию эта опция имеет значение true. Однако ей можно присвоить новое значение используя переменную среды **hostBuilder:reloadConfigOnChange** или передав её значение в качестве аргумента командной строки.

Некоторые настройки веб приложений имеют смысл только для приложений, которые обслуживают запросы. Чтобы настроить эти опции можно использовать переменные среды с префиксами DOTNET_ or ASPNETCORE_. Также для эти настроек доступы методы расширений на объекте IWebHostBuilder. Официальная документация Microsoft перечисляет 10 таких опций. Так как тема нашего видео урока «Хост приложения ASP.NET» и наш видео урок обзорный, что не подразумевает детальное рассмотрение всех аспектов данной темы, то я позволю себе не рассматривать сейчас эти опции. Я просто оставлю их список в описании к видео и, если Вам будет интересно, вы самостоятельно сможете проверить на что данные опции влияют. Список опций настроек для веб – приложения:

  1. CaptureStartupErrors
  2. DetailedErrors
  3. HostingStartupAssemblies
  4. HostingStartupExcludeAssemblies
  5. HTTPS_Port
  6. PreferHostingUrls
  7. PreventHostingStartup
  8. StartupAssembly
  9. URLs
  10. WebRoot

Для управления жизненным циклом приложения можно вызывать на объекте класса, который реализует интерфейс IHost методы для старта и окончания работы приложения. Также есть ряд методов расширений для объектов типа IHost. Все эти методы можно поделить на 3 группы:

  • Методы, которые начинаются со слова Run
  • Методы, которые начинаются со слов Start или Stop
  • Методы, которые начинаются со слова Wait

Надеюсь, что это видео было для вас интересным и полезным. Если это так, то буду благодарен за лайк и подписку, если вы еще не подписаны. Я не специалист в продвижении канала на youtube, но я слышал, что лайки и подписки помогают в продвижении. Также я слышал, что положительные комментарии помогают продвижении канала, а если это так, то я буду благодарен за такие комментарии под данным видео. Более того, чем интенсивнее канал развивается, тем более высока моя мотивация продолжать создавать данные видео. Спасибо за внимание и до новых встреч.

Пример кода из видео на GitHub

Для открытия файла проекта необходимо Visual Studio 2019.