Веб-узел ASP.NET Core

Примечание.

Это не последняя версия этой статьи. В текущей версии см. версию .NET 10 этой статьи.

Предупреждение

Эта версия ASP.NET Core больше не поддерживается. Дополнительные сведения см. в политике поддержки .NET и .NET Core. В текущей версии см. версию .NET 10 этой статьи.

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

В этой статье описывается веб-узел, доступ к которому предоставляется только для обеспечения обратной совместимости. Шаблоны ASP.NET Core создают WebApplicationBuilder и WebApplication, что рекомендуется для веб-приложений. Для получения дополнительной информации о WebApplicationBuilder и WebApplication, см. раздел "Миграция с ASP.NET Core в .NET 5 на .NET 6".

Настройка хоста

Создайте узел с помощью экземпляра IWebHostBuilder. Эта задача обычно выполняется в точке входа приложения, Main метод в файле Program.cs . Обычное приложение вызывает CreateDefaultBuilder метод для запуска настройки узла:

public class Program
{
    public static void Main(string[] args)
    {
        CreateWebHostBuilder(args).Build().Run();
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>();
}

Код, который вызывает CreateDefaultBuilder, находится в методе с именем CreateWebHostBuilder, который отделяет его от кода в Main, где производится вызов метода Run на объекте построителя. Разделение требуется, если вы используете средства Entity Framework Core. Инструменты ожидают найти метод CreateWebHostBuilder, который они могут вызвать на этапе проектирования для конфигурации узла без необходимости запускать приложение. Альтернативой является создание экземпляра IDesignTimeDBContextfactory. Подробные сведения см. в разделе Design-time DbContext Creation (Создание DbContext на этапе разработки).

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

Корень содержимого определяет, где хост ищет контент-файлы, например файлы представлений MVC. Когда приложение запускается из корневой папки проекта, эта папка используется в качестве корневого каталога содержимого. Это поведение по умолчанию для Visual Studio и новых шаблонов dotnet.

Дополнительные сведения о конфигурации приложения см. в разделе Конфигурация в ASP.NET Core.

Примечание.

В качестве альтернативы использованию статического CreateDefaultBuilder метода можно создать узел с WebHostBuilder помощью ASP.NET Core 2.x.

При настройке узла можно использовать методы Configure и ConfigureServices. Если используется класс Startup, в нем должен быть определен метод Configure. Подробные сведения см. в статье Запуск приложения в ASP.NET Core. Многократные вызовы ConfigureServices добавляют друг к другу. Несколько вызовов Configure или UseStartup на экземпляре WebHostBuilder заменяют все предыдущие настройки.

Методы переопределения конфигурации

Вы можете переопределить и расширить конфигурацию, определенную с помощью CreateDefaultBuilder. Используйте методы ConfigureAppConfiguration и ConfigureLogging, а также другие методы и методы расширения IWebHostBuilder.

Ниже приведены некоторые примеры.

  • ConfigureAppConfiguration используется для указания других IConfiguration свойств приложения. Следующий вызов метода ConfigureAppConfiguration добавляет делегат для включения конфигурации приложения в файлappsettings.xml . ConfigureAppConfiguration можно вызывать несколько раз. Эта конфигурация не применяется к узлу (например, URL-адресам сервера или среде). Дополнительные сведения см. в разделе "Значения конфигурации узла".

    WebHost.CreateDefaultBuilder(args)
        .ConfigureAppConfiguration((hostingContext, config) =>
        {
            config.AddXmlFile("appsettings.xml", optional: true, reloadOnChange: true);
        })
        ...
    
  • Следующий вызов ConfigureLogging добавляет делегата, чтобы настроить минимальный уровень ведения журнала (SetMinimumLevel) для LogLevel. Этот параметр переопределяет параметры в файле appsettings.Development.json () и LogLevel.Debug файле (LogLevel.Error), настроенном методомCreateDefaultBuilder. ConfigureLogging можно вызывать несколько раз.

    WebHost.CreateDefaultBuilder(args)
        .ConfigureLogging(logging => 
        {
            logging.SetMinimumLevel(LogLevel.Warning);
        })
        ...
    
  • Следующий вызов ConfigureKestrel переопределяет стандартное значение Limits.MaxRequestBodySize в 30 000 000 байт, заданное при настройке Kestrel с помощью метода CreateDefaultBuilder.

    WebHost.CreateDefaultBuilder(args)
        .ConfigureKestrel((context, options) =>
        {
            options.Limits.MaxRequestBodySize = 20000000;
        });
    

Настройка значений конфигурации веб-узла

Экземпляр WebHostBuilder использует следующие подходы к настройке значений конфигурации узла:

  • Конфигурация построителя хоста, которая включает переменные среды, использующие формат ASPNETCORE_{configurationKey}. Например, ASPNETCORE_ENVIRONMENT.

  • Расширения, такие как UseContentRoot и UseConfiguration. Дополнительные сведения см. в разделе "Переопределение конфигурации веб-узла".

  • Метод UseSetting и связанный ключ. Когда вы задаете значение с помощью UseSetting, оно устанавливается как строка, независимо от типа.

Хост использует последнюю установленную опцию. Дополнительные сведения см. в разделе "Переопределение конфигурации веб-узла".

Имя приложения

Определяет имя сборки, содержащей точку входа для приложения.

Ключ: applicationName
Тип: string
По умолчанию: имя сборки с точкой входа приложения.
Задается с помощью: UseSetting
Переменная среды: ASPNETCORE_APPLICATIONNAME

Свойство IWebHostEnvironment.ApplicationName автоматически задается при вызове метода UseStartup или Configure во время построения хоста. Чтобы явно задать значение, используйте ApplicationKey поле.

WebHost.CreateDefaultBuilder(args)
    .UseSetting(WebHostDefaults.ApplicationKey, "CustomApplicationName")

Запись ошибок запуска

Управляет записью ошибок запуска.

Ключ: captureStartupErrors
Тип: bool (true или 1)
по умолчанию: false. Если приложение выполняется за IIS, значение по умолчанию — Kestrel.
Задается с помощью: CaptureStartupErrors
Переменная среды: ASPNETCORE_CAPTURESTARTUPERRORS

Если задано значение false, ошибки во время запуска приводят к завершению работы хоста. Если задано значение true, хост перехватывает исключения во время запуска и пытается запустить сервер.

WebHost.CreateDefaultBuilder(args)
    .CaptureStartupErrors(true)

Корневой каталог содержимого

Определяет, где начинается поиск файлов содержимого ASP.NET Core.

Ключ: contentRoot
Тип: string
По умолчанию: папка, содержащая сборку приложения.
Задается с помощью: UseContentRoot
Переменная среды: ASPNETCORE_CONTENTROOT

Корневой каталог содержимого также используется в качестве базового пути для веб-корня. Если путь к корневому каталогу содержимого не существует, сервер не запускается.

WebHost.CreateDefaultBuilder(args)
    .UseContentRoot("c:\\<content-root>")

Дополнительные сведения см. в разделе:

Подробные ошибки

Определяет, следует ли записывать подробные ошибки.

Ключ: detailedErrors
Тип: bool (true или 1)
По умолчанию:false
Задается с помощью: UseSetting
Переменная среды: ASPNETCORE_DETAILEDERRORS

При включении (или когда значение среды установлено на Development), приложение записывает подробные исключения.

WebHost.CreateDefaultBuilder(args)
    .UseSetting(WebHostDefaults.DetailedErrorsKey, "true")

Окружающая среда

Задает среду приложения.

Ключ: environment
Тип: string
По умолчанию:Production
Задается с помощью: UseEnvironment
Переменная среды: ASPNETCORE_ENVIRONMENT

В качестве среды можно указать любое значение. В платформе определены значения Development, Staging и Production. Регистр символов в значениях не учитывается.

По умолчанию значение параметра Среда считывается из переменной среды ASPNETCORE_ENVIRONMENT. При использовании Visual Studio переменные среды можно задать в файлеlaunchSettings.json . Дополнительные сведения см. в ASP.NET средах выполнения Core.

WebHost.CreateDefaultBuilder(args)
    .UseEnvironment(EnvironmentName.Development)

Проведение встреч для стартапов

Предоставляет строку с запятой для размещения сборок запуска для загрузки при запуске.

Ключ: hostingStartupAssemblies
Тип: string
Значение по умолчанию: пустая строка.
Задается с помощью: UseSetting
Переменная среды: ASPNETCORE_HOSTINGSTARTUPASSEMBLIES

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

WebHost.CreateDefaultBuilder(args)
    .UseSetting(WebHostDefaults.HostingStartupAssembliesKey, "assembly1;assembly2")

Порт HTTPS

Задает порт HTTPS для перенаправления при получении подключения, отличного от HTTPS.

Ключ: https_port
Тип: string
Значение по умолчанию: нет по умолчанию.
Задается с помощью: UseSetting
Переменная среды: ASPNETCORE_HTTPS_PORT

Этот параметр используется при принудительном применении ПРОТОКОЛА HTTPS. Этот параметр не приводит к тому, что сервер будет прослушивать указанный порт. То есть можно случайно перенаправить запросы на неиспользуемый порт.

WebHost.CreateDefaultBuilder(args)
    .UseSetting("https_port", "8080")

Размещение стартапа исключает сборки

Предоставляет строку с запятой для размещения сборок запуска, которые следует исключить при запуске.

Ключ: hostingStartupExcludeAssemblies
Тип: string
Значение по умолчанию: пустая строка.
Задается с помощью: UseSetting
Переменная среды: ASPNETCORE_HOSTINGSTARTUPEXCLUDEASSEMBLIES

WebHost.CreateDefaultBuilder(args)
    .UseSetting(WebHostDefaults.HostingStartupExcludeAssembliesKey, "assembly1;assembly2")

Предпочитать URL-адреса размещения

Указывает, должен ли узел прослушивать URL-адреса, настроенные с WebHostBuilder, вместо URL-адресов, настроенных с реализацией IServer.

Ключ: preferHostingUrls
Тип: bool (true или 1)
По умолчанию:false
Задается с помощью: PreferHostingUrls
Переменная среды: ASPNETCORE_PREFERHOSTINGURLS

WebHost.CreateDefaultBuilder(args)
    .PreferHostingUrls(true)

Предотвратить запуск хостинга

Запрещает автоматическую загрузку начальных сборок хостинга, включая сборки хостинга, настроенные самой сборкой приложения. Дополнительную информацию см. в статье Использование начальных сборок для размещения в ASP.NET Core.

Ключ: preventHostingStartup
Тип: bool (true или 1)
По умолчанию:false
Задается с помощью: UseSetting
Переменная среды: ASPNETCORE_PREVENTHOSTINGSTARTUP

WebHost.CreateDefaultBuilder(args)
    .UseSetting(WebHostDefaults.PreventHostingStartupKey, "true")

URL-адреса сервера

Задает IP-адреса или адреса узлов с портами и протоколами, по которым сервер должен ожидать получения запросов.

Ключ: urls
Тип: string
По умолчанию:http://localhost:5000
Задается с помощью: UseUrls
Переменная среды: ASPNETCORE_URLS

Задайте для списка префиксов URL-адресов, разделенных точкой с запятой ;, на которые должен отвечать сервер. Например, http://localhost:123. Используйте подстановочный символ звездочка *, чтобы указать, что сервер должен прослушивать запросы с любого IP-адреса или узла, с использованием указанного порта и протокола (например, http://*:5000). Протокол (http:// или https://) должен указываться для каждого URL-адреса. Поддерживаемые форматы зависят от сервера.

WebHost.CreateDefaultBuilder(args)
    .UseUrls("http://*:5000;http://localhost:5001;https://hostname:5002")

Kestrel имеет собственный API настройки конечных точек. Дополнительные сведения см. в разделе "Настройка конечных точек для Kestrel веб-сервера".

Время ожидания завершения работы

Указывает время ожидания завершения работы веб-узла.

Ключ: shutdownTimeoutSeconds
Тип: int
Значение по умолчанию: 5 секунд
Задается с помощью: UseShutdownTimeout
Переменная среды: ASPNETCORE_SHUTDOWNTIMEOUTSECONDS

Хотя ключ принимает int как UseSetting (например, .UseSetting(WebHostDefaults.ShutdownTimeoutKey, "10")), метод расширения UseShutdownTimeout принимает параметр TimeSpan.

В течение времени ожидания веб-хост:

  • Активирует ApplicationStopping.
  • Проводятся попытки остановить хостинговые службы, ведется запись в журнал всех ошибок для служб, которые не удалось остановить.

Если срок ожидания истекает до остановки всех размещенных служб, все оставшиеся активные службы останавливаются при завершении работы приложения. Службы останавливаются, даже если они по-прежнему обрабатываются. Если службе требуется больше времени для остановки, увеличьте время ожидания.

WebHost.CreateDefaultBuilder(args)
    .UseShutdownTimeout(TimeSpan.FromSeconds(10))

Запуск сборки

Указывает сборку для поиска класса Startup.

Ключ: startupAssembly
Тип: string
По умолчанию: сборка приложения.
Задается с помощью: UseStartup
Переменная среды: ASPNETCORE_STARTUPASSEMBLY

Можно ссылаться на сборку по имени (string) или типу (TStartup). Если вызывается несколько UseStartup методов, последний вызов имеет приоритет.

WebHost.CreateDefaultBuilder(args)
    .UseStartup("StartupAssemblyName")
WebHost.CreateDefaultBuilder(args)
    .UseStartup<TStartup>()

корневая папка веб-сайта

Задает относительный путь к статическим ресурсам приложения.

Ключ: webroot
Тип: string
По умолчанию:wwwroot
Задается с помощью: UseWebRoot
Переменная среды: ASPNETCORE_WEBROOT

Путь к {content root}/wwwroot должен существовать. Если этот путь не существует, используется фиктивный поставщик файлов.

WebHost.CreateDefaultBuilder(args)
    .UseWebRoot("public")

Дополнительные сведения см. в разделе:

Переопределите конфигурацию веб-узла

Используйте конфигурацию приложения в ASP.NET Core для настройки веб-узла.

В следующем примере конфигурация узла при необходимости указывается в файлеhostsettings.json . Аргументы командной строки могут переопределить любую конфигурацию, загруженную из файла hostsettings.json . Созданная конфигурация используется для настройки узла с помощью метода UseConfiguration. IWebHostBuilder конфигурация добавляется в конфигурацию приложения, но обратное не верно. Метод ConfigureAppConfiguration не влияет на конфигурацию IWebHostBuilder .

Переопределение конфигурации, предоставленной UseUrls, с помощью конфигурации hostsettings.json, а затем - конфигурацией аргумента командной строки:

public class Program
{
    public static void Main(string[] args)
    {
        CreateWebHostBuilder(args).Build().Run();
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args)
    {
        var config = new ConfigurationBuilder()
            .SetBasePath(Directory.GetCurrentDirectory())
            .AddJsonFile("hostsettings.json", optional: true)
            .AddCommandLine(args)
            .Build();

        return WebHost.CreateDefaultBuilder(args)
            .UseUrls("http://*:5000")
            .UseConfiguration(config)
            .Configure(app =>
            {
                app.Run(context => 
                    context.Response.WriteAsync("Hello, World!"));
            });
    }
}

Содержимое файла hostsettings.json :

{
    urls: "http://*:5005"
}

Примечание.

Метод UseConfiguration копирует только ключи из предоставленной IConfiguration в конфигурацию сборщика хоста. Поэтому установка свойства reloadOnChange: true для файлов параметров JSON, INI и XML не оказывает никакого эффекта.

Чтобы указать узел, работающий на указанном URL-адресе, можно передать желаемое значение из командной строки при выполнении команды dotnet run. Аргумент командной строки переопределяет значение из файла hostsettings.json, а сервер прослушивает порт 8080.

dotnet run --urls "http://*:8080"

Управление веб-узлом

Для управления веб-узлом используйте следующие методы.

Run

Метод Run запускает веб-приложение и блокирует вызывающий поток до тех пор, пока работа узла не будет завершена.

host.Run();

Start

Запустите хост в неблокирующем режиме, вызвав его Start метод:

using (host)
{
    host.Start();
    Console.ReadLine();
}

Если в метод Start передается список URL-адресов, он будет прослушивать указанные URL-адреса.

var urls = new List<string>()
{
    "http://*:5000",
    "http://localhost:5001"
};

var host = new WebHostBuilder()
    .UseKestrel()
    .UseStartup<Startup>()
    .Start(urls.ToArray());

using (host)
{
    Console.ReadLine();
}

Приложение может инициализировать и запустить новый хост с предварительно настроенными значениями по умолчанию с помощью статического вспомогательного метода CreateDefaultBuilder. Эти методы запускают сервер без вывода консоли и используют WaitForShutdown метод, который ожидает перерыва (CTRL+C/SIGINT (Windows)/SIGINT (Windows), CTRL+C (macOS) или SIGTERM).

Start(RequestDelegate app)

Запустите хост с помощью RequestDelegate:

using (var host = WebHost.Start(app => app.Response.WriteAsync("Hello, World!")))
{
    Console.WriteLine("Use Ctrl-C to shutdown the host...");
    host.WaitForShutdown();
}

Отправьте запрос в браузере http://localhost:5000 по URL-адресу, чтобы получить ответ "Hello World!" Метод WaitForShutdown блокируется до тех пор, пока не будет выдан перерыв (CTRL-C/SIGINT или SIGTERM). Приложение выводит сообщение Console.WriteLine и ожидает нажатия клавиши, после чего завершает работу.

Start(string url, RequestDelegate app)

Запустите сервер с URL-адресом и RequestDelegate.

using (var host = WebHost.Start("http://localhost:8080", app => app.Response.WriteAsync("Hello, World!")))
{
    Console.WriteLine("Use Ctrl-C to shutdown the host...");
    host.WaitForShutdown();
}

Создает тот же результат, что и Start(RequestDelegate app), за исключением того, что приложение отвечает на http://localhost:8080 URL-адрес.

Start(Action<IRouteBuilder> routeBuilder)

Запустите хост, начиная с экземпляра IRouteBuilder, который использует посредника для маршрутизации:

using (var host = WebHost.Start(router => router
    .MapGet("hello/{name}", (req, res, data) => 
        res.WriteAsync($"Hello, {data.Values["name"]}!"))
    .MapGet("buenosdias/{name}", (req, res, data) => 
        res.WriteAsync($"Buenos dias, {data.Values["name"]}!"))
    .MapGet("throw/{message?}", (req, res, data) => 
        throw new Exception((string)data.Values["message"] ?? "Uh oh!"))
    .MapGet("{greeting}/{name}", (req, res, data) => 
        res.WriteAsync($"{data.Values["greeting"]}, {data.Values["name"]}!"))
    .MapGet("", (req, res, data) => res.WriteAsync("Hello, World!"))))
{
    Console.WriteLine("Use Ctrl-C to shutdown the host...");
    host.WaitForShutdown();
}

В этом примере используйте следующие запросы в браузере:

Запрос Ответ
http://localhost:5000/hello/Martin Привет, Мартин!
http://localhost:5000/buenosdias/Catrina Буэнос-Диас, Катрина!
http://localhost:5000/throw/ooops! Создает исключение со строкой "oops!"
http://localhost:5000/throw Вызывает исключение со строкой "Uh oh!"
http://localhost:5000/Sante/Kevin Санте, Кевин!
http://localhost:5000 Всем привет!

Метод WaitForShutdown блокируется до тех пор, пока не будет выдан перерыв (CTRL-C/SIGINT или SIGTERM). Приложение выводит сообщение Console.WriteLine и ожидает нажатия клавиши, после чего завершает работу.

Start(string url, Action<IRouteBuilder> routeBuilder)

Запустите хост, указав URL-адрес и экземпляр IRouteBuilder.

using (var host = WebHost.Start("http://localhost:8080", router => router
    .MapGet("hello/{name}", (req, res, data) => 
        res.WriteAsync($"Hello, {data.Values["name"]}!"))
    .MapGet("buenosdias/{name}", (req, res, data) => 
        res.WriteAsync($"Buenos dias, {data.Values["name"]}!"))
    .MapGet("throw/{message?}", (req, res, data) => 
        throw new Exception((string)data.Values["message"] ?? "Uh oh!"))
    .MapGet("{greeting}/{name}", (req, res, data) => 
        res.WriteAsync($"{data.Values["greeting"]}, {data.Values["name"]}!"))
    .MapGet("", (req, res, data) => res.WriteAsync("Hello, World!"))))
{
    Console.WriteLine("Use Ctrl-C to shut down the host...");
    host.WaitForShutdown();
}

Создает тот же результат, что и Start(Action<IRouteBuilder> routeBuilder), за исключением того, что приложение отвечает на конкретный http://localhost:8080 URL-адрес.

StartWith(Action<IApplicationBuilder> приложение)

Запустите хост, начиная с делегата, который настраивает IApplicationBuilder:

using (var host = WebHost.StartWith(app => 
    app.Use(next => 
    {
        return async context => 
        {
            await context.Response.WriteAsync("Hello World!");
        };
    })))
{
    Console.WriteLine("Use Ctrl-C to shut down the host...");
    host.WaitForShutdown();
}

Отправьте запрос в браузере http://localhost:5000 по URL-адресу, чтобы получить ответ "Hello World!" Метод WaitForShutdown блокируется до тех пор, пока не будет выдан перерыв (CTRL-C/SIGINT или SIGTERM). Приложение выводит сообщение Console.WriteLine и ожидает нажатия клавиши, после чего завершает работу.

StartWith(строковый URL-адрес, приложение Action<IApplicationBuilder> )

Запустите хост, начав с URL-адреса и делегата, который настраивает IApplicationBuilder.

using (var host = WebHost.StartWith("http://localhost:8080", app => 
    app.Use(next => 
    {
        return async context => 
        {
            await context.Response.WriteAsync("Hello World!");
        };
    })))
{
    Console.WriteLine("Use Ctrl-C to shut down the host...");
    host.WaitForShutdown();
}

Создает тот же результат, что и приложение StartWith(Action<IApplicationBuilder> ), за исключением того, что приложение отвечает на http://localhost:8080 URL-адрес.

Использование интерфейса IWebHostEnvironment

Интерфейс IWebHostEnvironment предоставляет сведения о среде веб-размещения приложения. Используйте конструкторную инъекцию для получения экземпляра IWebHostEnvironment, и затем получите доступ к его свойствам и методам расширения.

public class CustomFileReader
{
    private readonly IWebHostEnvironment _env;

    public CustomFileReader(IWebHostEnvironment env)
    {
        _env = env;
    }

    public string ReadFile(string filePath)
    {
        var fileProvider = _env.WebRootFileProvider;
        // Process the file here
    }
}

Для настройки приложения при запуске в соответствии со средой можно применять подход на основе соглашения. В качестве альтернативы, введите экземпляр IWebHostEnvironment в конструктор Startup для использования в методе ConfigureServices:

public class Startup
{
    public Startup(IWebHostEnvironment env)
    {
        HostingEnvironment = env;
    }

    public IWebHostEnvironment HostingEnvironment { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        if (HostingEnvironment.IsDevelopment())
        {
            // Development configuration
        }
        else
        {
            // Staging/Production configuration
        }

        var contentRootPath = HostingEnvironment.ContentRootPath;
    }
}

Примечание.

IsDevelopment Помимо метода расширения, IWebHostEnvironment предлагает методы IsStaging, IsProduction и IsEnvironment(string environmentName). Дополнительные сведения см. в ASP.NET средах выполнения Core.

Службу IWebHostEnvironment также можно внедрять непосредственно в метод Configure для настройки конвейера обработки:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        // In Development, use the Developer Exception Page
        app.UseDeveloperExceptionPage();
    }
    else
    {
        // In Staging/Production, route exceptions to /error
        app.UseExceptionHandler("/error");
    }

    var contentRootPath = env.ContentRootPath;
}

IWebHostEnvironment можно внедрять в метод Invoke при создании пользовательского среднего программного обеспечения:

public async Task Invoke(HttpContext context, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        // Configure middleware for Development
    }
    else
    {
        // Configure middleware for Staging/Production
    }

    var contentRootPath = env.ContentRootPath;
}

Использование интерфейса IHostApplicationLifetime

Интерфейс IHostApplicationLifetime позволяет выполнять действия после запуска и завершения работы. Три свойства этого интерфейса представляют собой токены отмены, которые служат для регистрации методов Action, определяющих события запуска и завершения работы.

Маркер отмены Trigger
ApplicationStarted Хост полностью запущен.
ApplicationStopped Заканчивается плавное завершение работы хоста. Ожидается, что все запросы будут обработаны. Завершение процесса приостанавливается до тех пор, пока это событие не завершится.
ApplicationStopping Происходит корректное завершение работы хоста. Запросы все еще могут находиться в обработке. Завершение процесса приостанавливается до тех пор, пока это событие не завершится.
public class Startup
{
    public void Configure(IApplicationBuilder app, IHostApplicationLifetime appLifetime)
    {
        appLifetime.ApplicationStarted.Register(OnStarted);
        appLifetime.ApplicationStopping.Register(OnStopping);
        appLifetime.ApplicationStopped.Register(OnStopped);

        Console.CancelKeyPress += (sender, eventArgs) =>
        {
            appLifetime.StopApplication();
            // Don't terminate the process immediately, wait for the Main thread to exit gracefully.
            eventArgs.Cancel = true;
        };
    }

    private void OnStarted()
    {
        // Perform post-startup activities here
    }

    private void OnStopping()
    {
        // Perform on-stopping activities here
    }

    private void OnStopped()
    {
        // Perform post-stopped activities here
    }
}

Метод StopApplication запрашивает завершение приложения. Следующий класс использует StopApplication для корректного завершения работы приложения при вызове метода класса Shutdown:

public class MyClass
{
    private readonly IHostApplicationLifetime _appLifetime;

    public MyClass(IHostApplicationLifetime appLifetime)
    {
        _appLifetime = appLifetime;
    }

    public void Shutdown()
    {
        _appLifetime.StopApplication();
    }
}

Настройка проверки области

Метод CreateDefaultBuilder устанавливает значение ValidateScopes для свойства true, если среда приложения равна Development.

Если ValidateScopes задано значение true, поставщик служб по умолчанию выполняет проверки:

  • Службы с заданной областью не разрешаются из корневого поставщика службы, прямо или косвенно.
  • Службы с заданной областью не вводятся в одноэлементные объекты, прямо или косвенно.

Поставщик корневой службы создается при вызове BuildServiceProvider метода. Время существования корневого поставщика службы соответствует времени существования приложения или сервера — поставщик запускается с приложением и удаляется, когда приложение завершает работу.

Контейнер, создавший службы с областью действия, также удаляет службы. Если служба с заданной областью создается в корневом контейнере, время существования службы эффективно повышается до одноэлементного. Корневой контейнер удаляет службу только при завершении работы приложения или сервера. Проверка областей применения службы обнаруживает эти ситуации при вызове BuildServiceProvider.

Чтобы всегда проверять контексты, включая в Production среде, настройте объект ServiceProviderOptions методом UseDefaultServiceProvider в строителе хоста:

WebHost.CreateDefaultBuilder(args)
    .UseDefaultServiceProvider((context, options) => {
        options.ValidateScopes = true;
    })