Как устроен ASP.NET Core: Kestrel, хост, Program.cs, WebApplication

↑ 3.1 Хост, конфигурация и middleware pipeline · → Следующая

Обязательно~4 мин чтенияУровень: middle

Зачем это на собесе

«Что происходит от dotnet run до первого запроса?» — стартовый вопрос по ASP.NET Core. Он проверяет понимание хоста, DI и конвейера.

Объяснение

Приложение ASP.NET Core — это консольное приложение, которое создаёт хост (IHost). Хост владеет DI-контейнером, конфигурацией, логированием и набором IHostedService, среди которых веб-сервер Kestrel.

var builder = WebApplication.CreateBuilder(args);   // конфигурация, DI, логирование по умолчанию
 
builder.Services.AddControllers();                  // регистрация сервисов
builder.Services.AddScoped<IOrderService, OrderService>();
 
var app = builder.Build();                          // сборка контейнера и конвейера
 
app.UseExceptionHandler();                          // конвейер middleware
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();                               // endpoints
 
app.Run();                                          // запуск Kestrel и блокировка потока
КомпонентРоль
Kestrelкроссплатформенный HTTP-сервер внутри процесса, HTTP/1.1, HTTP/2, HTTP/3
WebApplicationBuilderсобирает конфигурацию, сервисы, логирование
WebApplicationодновременно IApplicationBuilder (middleware) и IEndpointRouteBuilder (маршруты)
Reverse proxy (nginx, YARP, IIS)TLS, балансировка, статические файлы, защита Kestrel от интернета
IHostedServiceфоновые сервисы и сам сервер

Что делает CreateBuilder

  1. Устанавливает ContentRoot, читает appsettings.json, appsettings.{Environment}.json, user secrets (в Development), переменные окружения, аргументы командной строки.
  2. Подключает логирование (Console, Debug, EventSource).
  3. Включает DI-контейнер с проверкой областей видимости в Development.
  4. Настраивает Kestrel и UseUrls/ASPNETCORE_URLS.

Жизненный цикл запроса

Сокет Kestrel → парсинг HTTP → HttpContext → цепочка middleware → routing выбирает endpoint → фильтры/обработчик → ответ проходит обратно через middleware.

Minimal hosting и Startup

До .NET 6 использовались Program.cs + Startup.cs (ConfigureServices, Configure). Модель minimal hosting объединила это в один файл; функционально они эквивалентны.

Нюансы и подводные камни

  • Порядок вызовов Use* важен: это порядок конвейера (см. Middleware: конвейер, порядок, свои middleware).
  • После builder.Build() регистрировать сервисы нельзя: контейнер неизменяем.
  • Kestrel не стоит выставлять напрямую в интернет без proxy, если нужна защита от медленных клиентов и TLS-терминация в ingress.
  • В Docker слушайте http://+:8080 (порт по умолчанию с .NET 8 — 8080, не 80).
  • app.Run() блокирует поток до сигнала остановки (SIGTERM/Ctrl+C); используйте RunAsync в тестах.

Практика

  1. Создайте пустое приложение и выведите список зарегистрированных сервисов и endpoints.
  2. Запустите одно и то же приложение за nginx и напрямую, сравните заголовки (X-Forwarded-*).
  3. Переведите старый проект со Startup.cs на minimal hosting.

Вопросы с ответами

Связанные темы