Содержание
Класс WebApplication
реализует сразу три интерфейса IHost
, IApplicationBuilder
и IEndpointRouteBuilder
и используется для широкого круга задач — от запуска и остановки приложения, до настройки маршрутов, с которыми сопоставляются запросы пользователей, конвейера обработки запросов и получения доступа к настройкам приложения.
Свойства и методы класса WebApplication
Объект этого класса создается при вызове метода Build()
класса WebApplicationBuilder
var builder = WebApplication.CreateBuilder(args); //настройка приложения var app = builder.Build(); //создаем объект типа WebApplication // получение доступа к настройкам приложения
Класс WebApplication
предоставляет свойства, представленные в таблице:
Свойство | Значение свойства | Описание |
Configuration |
IConfiguration |
представляет конфигурацию приложения в виде объекта IConfiguration |
Environment |
IWebHostEnvironment |
представляет данные об окружении приложения в виде IWebHostEnvironment |
Lifetime |
IHostApplicationLifetime |
позволяет пользователям получать уведомления о событиях жизненного цикла приложения |
Logger |
ILogger |
представляет объект для ведения журнала для приложения |
Services |
IServiceProvider |
представляет список сервисов приложения |
Urls |
ICollection<String> |
представляет список URL-адресов, к которым привязан HTTP-сервер. |
Кроме того, класс WebApplication
содержит методы для управления приложением
Метод | Описание |
Run(String) |
Запускает приложение и блокирует вызывающий поток, пока работа узла не будет завершена. В параметре метода можно указать url по которому будет доступно приложение. |
RunAsync(String) |
Запускает приложение и возвращает объект Task , который завершается только при активации токена или завершении работы |
StartAsync(CancellationToken) |
Запускает приложение |
StopAsync(CancellationToken) |
Завершает работу приложения |
Запуск и остановка приложения
Чтобы понять суть работы методов у WebApplication, создадим новый проект ASP.NET Core Web API и добавим в самый конец файла строку:
var builder = WebApplication.CreateBuilder(args); builder.Services.AddControllers(); builder.Services.AddOpenApi(); var app = builder.Build(); if (app.Environment.IsDevelopment()) { app.MapOpenApi(); } app.UseHttpsRedirection(); app.UseAuthorization(); app.MapControllers(); app.Run(); //новая строка кода app.Logger.LogInformation("Приложение запущено");
Здесь мы пытаемся вывести в лог строку «Приложение запущено» после того, как выполняется метод Run()
. Забегая немного вперед, отмечу, что по умолчанию приложение настраивается на ведение лога в том числе в консоли. Если вы запустите приложение, то увидите, что в консоль ничего не будет выведено так как метод Run()
блокирует вызывающий поток. То же самое произойдет и при попытке запуска приложения с использованием метода RunAsync()
.
Если мы хотим произвести какие-либо действия уже после того, как приложение запущено, нам необходимо использовать метод StartAsync()
. Перепишем код приложение следующим образом
var builder = WebApplication.CreateBuilder(args); builder.Services.AddControllers(); builder.Services.AddOpenApi(); var app = builder.Build(); if (app.Environment.IsDevelopment()) { app.MapOpenApi(); } app.UseHttpsRedirection(); app.UseAuthorization(); app.MapControllers(); await app.StartAsync(); app.Logger.LogInformation("Приложение запущено"); await app.WaitForShutdownAsync();
Теперь мы используем для запуска приложения метод StartAsync()
, который не будет блокировать вызывающий поток, а сразу после запуска вернет результат.
Для того, чтобы приложение не завершило работу после вывода сообщения в консоль мы также добавили в конце вызов метода WaitForShutdownAsync()
, который вернет нам результат только после того, как приложение завершит свою работу. Теперь можно запустить приложение и убедиться, что строка с сообщением выведена в консоль
Также стоит отметить, что, если вам по каким-то причинам, потребуется вручную остановить работу приложения, то можно использоваться связку методов: StartAsync()
– для запуска и StopAsync()
– для остановки приложения.
Доступ к событиям жизненного цикла приложения
Иногда может потребоваться волнение каких-либо действий в момент запуска приложения или, наоборот, в момент, когда приложение начинает свою остановку. Для этого мы можем получить доступ к событиям жизненного цикла приложения. Свойство Lifetime
класса WebApplication
реализует интерфейс IHostApplicationLifetime
у которого определены следующие свойства
Свойство | Тип | Описание |
ApplicationStarted |
CancellationToken |
Срабатывает при полной загрузке узла приложения |
ApplicationStopped |
CancellationToken |
Срабатывает, когда узел приложения выполнил корректное завершение работы |
ApplicationStopping |
CancellationToken |
Срабатывает, когда хост приложения выполняет корректное завершение работы. Завершение работы будет блокироваться до завершения этого события |
Таким образом, используя эти свойства, мы можем отслеживать жизненный цикла нашего приложения – когда оно полностью запущено, начало корректное завершение работы и когда приложение полностью завершает свою работу. Продемонстрировать работу с этими свойствами можно на следующем примере:
var builder = WebApplication.CreateBuilder(args); builder.Services.AddControllers(); // Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi builder.Services.AddOpenApi(); var app = builder.Build(); if (app.Environment.IsDevelopment()) { app.MapOpenApi(); } app.UseHttpsRedirection(); app.UseAuthorization(); app.MapControllers(); app.Lifetime.ApplicationStarted.Register(() => InvokeEvent(app.Logger,"Приложение запущено")); app.Lifetime.ApplicationStopping.Register(() => InvokeEvent(app.Logger, "Приложение начало корректную остановку")); app.Lifetime.ApplicationStopped.Register(() => InvokeEvent(app.Logger, "Приложение полностью остановлено")); app.Run(); void InvokeEvent(ILogger logger, string text) { logger.LogInformation($"{DateTime.Now} {text}"); }
Прежде всего, мы регистрируем функцию обратного вызова, код которой будет выполняться при срабатывании свойств объекта Lifetime: OnStarted()
, OnStopping()
и OnStopped()
:
app.Lifetime.ApplicationStarted.Register(() => InvokeEvent(app.Logger,"Приложение запущено")); app.Lifetime.ApplicationStopping.Register(() => InvokeEvent(app.Logger, "Приложение начало корректную остановку")); app.Lifetime.ApplicationStopped.Register(() => InvokeEvent(app.Logger, "Приложение полностью остановлено"));
Сама функция обратного вызова достаточно простая
void InvokeEvent(ILogger logger, string text) { logger.LogInformation($"{DateTime.Now} {text}"); }
Здесь мы запрашиваем в параметрах методов сервис для ведения логов – ILogger
и выводим сообщение в лог об очередном событии жизненного цикла
Теперь запустим приложение в режиме отладки. В консоли мы должны увидеть первое сообщение об успешном запуске
Теперь, находясь в консоли приложения, нажмем сочетание клавиш Ctrl+C, что приведет к остановке приложения и мы увидим сообщения о ходе процесса остановки приложения
Как нетрудно догадаться, вместо простого вывода строки в лог приложения, внутри методов обратного вызова мы могли бы производить какую-либо полезную работу – запустить или остановить внешние процессы, используемые приложением, сохранить результаты работы и так далее.
Итого
Класс WebApplication
используется для широкого круга задач. В этой части мы рассмотрели различные варианты запуска приложения, а также работу со свойством Lifetime
, используя которое, мы можем получить доступ к событиям жизненного цикла приложения.