Содержание
Класс 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, используя которое, мы можем получить доступ к событиям жизненного цикла приложения.


