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

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

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

В этой статье описывается веб-узел, который предназначен для размещения веб-приложений. Для приложений других типов используйте универсальный узел.

Создание узла

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

В шаблонах проектов метод 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 выполняет указанные ниже задачи.

Настройки, определенные 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.Warning. Этот параметр переопределяет параметры в appsettings.Development.json (LogLevel.Debug) и appsettings.Production.json (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;
        });
    
  • При следующем вызове к UseKestrel переопределяется значение по умолчанию Limits.MaxRequestBodySize, равное 30 000 000 байтов, установленное при настройке Kestrel с помощью CreateDefaultBuilder:

    WebHost.CreateDefaultBuilder(args)
        .UseKestrel(options =>
        {
            options.Limits.MaxRequestBodySize = 20000000;
        });
    

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

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

Примечание

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

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

Значения конфигурации узла

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

  • конфигурация построителя узла, которая включает в себя переменные среды в формате ASPNETCORE_{configurationKey}, Например, ASPNETCORE_ENVIRONMENT.
  • Расширения, такие как UseContentRoot и UseConfiguration (см. раздел Переопределение конфигурации).
  • метод UseSetting и связанный ключ. Значение, задаваемое с помощью UseSetting, всегда является строкой независимо от типа.

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

Ключ приложения (имя)

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

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

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

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

Перехват ошибок при загрузке

Этот параметр управляет перехватом ошибок при загрузке.

Ключ: captureStartupErrors
Тип: bool (true или 1)
Значение по умолчанию: false, если только приложение не работает с сервером Kestrel за IIS; в этом случае значение по умолчанию — true.
Задается с помощью: 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
По умолчанию: Рабочие
Задается с помощью: 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

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

Исключаемые начальные сборки размещения

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

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

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

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

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

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

WebHost.CreateDefaultBuilder(args)
    .PreferHostingUrls(false)

Запретить запуск размещения

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

Kestrel имеет собственный API настройки конечных точек. Для получения дополнительной информации см. Реализация веб-сервера Kestrel в ASP.NET Core.

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

Определяет, как долго необходимо ожидать завершения работы веб-узла.

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

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

Во время ожидания размещение:

  • Активирует IApplicationLifetime.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. Наличие пути {корневой_каталог_содержимого}/wwwroot обязательно. Если этот путь не существует, используется фиктивный поставщик файлов.
Задается с помощью: UseWebRoot
Переменная среды: ASPNETCORE_WEBROOT

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

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

Переопределение конфигурации

Используйте конфигурацию для настройки веб-узла. В приведенном ниже примере необязательная конфигурация узла задается в файле hostsettings.json. Любую конфигурацию, загружаемую из файла hostsettings.json, можно переопределить с помощью аргументов командной строки. Встроенная конфигурация (в config) используется для настройки узла с помощью 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, XML и INI ни на что не влияет.

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

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

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

Выполнить

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

host.Run();

Запуск

Чтобы запустить узел без блокировки, вызовите метод 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 или 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, чтобы получить ответ "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.

Start(Action<IRouteBuilder> routeBuilder)

Используйте экземпляр IRouteBuilder (Microsoft.AspNetCore.Routing) для применения ПО промежуточного слоя маршрутизации:

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 Hello, Martin!
http://localhost:5000/buenosdias/Catrina Buenos dias, Catrina!
http://localhost:5000/throw/ooops! Вызывает исключение со строкой "ooops!"
http://localhost:5000/throw Вызывает исключение со строкой "Uh oh!"
http://localhost:5000/Sante/Kevin 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.

StartWith(Action<IApplicationBuilder> app)

Предоставьте делегат для настройки 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, чтобы получить ответ "Hello World!" WaitForShutdown блокируется, пока не будет создано прерывание (Ctrl-C/SIGINT или SIGTERM). Приложение выводит сообщение Console.WriteLine и ожидает нажатия клавиши, после чего завершает работу.

StartWith(string url, Action<IApplicationBuilder> app)

Предоставьте 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> app) , но приложение отвечает по адресу http://localhost:8080.

Интерфейс 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;
}

Интерфейс IHostingEnvironment

Интерфейс IHostingEnvironment предоставляет сведения о среде веб-размещения приложения. Чтобы получить интерфейс IHostingEnvironment для использования его свойств и методов расширения, воспользуйтесь внедрением конструктора:

public class CustomFileReader
{
    private readonly IHostingEnvironment _env;

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

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

Для настройки приложения при запуске в соответствии со средой можно применять подход на основе соглашения. Кроме того, можно внедрить интерфейс IHostingEnvironment в конструктор Startup для использования в ConfigureServices:

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

    public IHostingEnvironment HostingEnvironment { get; }

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

        var contentRootPath = HostingEnvironment.ContentRootPath;
    }
}

Примечание

Помимо метода расширения IsDevelopment, интерфейс IHostingEnvironment предоставляет методы IsStaging, IsProduction и IsEnvironment(string environmentName). Для получения дополнительной информации см. Использование нескольких сред в ASP.NET Core.

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

public void Configure(IApplicationBuilder app, IHostingEnvironment 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;
}

IHostingEnvironment можно внедрить в метод Invoke при создании пользовательского ПО промежуточного слоя:

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

    var contentRootPath = env.ContentRootPath;
}

Интерфейс IHostApplicationLifetime

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

Токен отмены Условие инициации…
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();
    }
}

Интерфейс IApplicationLifetime

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

Токен отмены Условие инициации…
ApplicationStarted Узел полностью запущен.
ApplicationStopped Заканчивается нормальное завершение работы узла. Все запросы должны быть обработаны. Завершение работы блокируется до тех пор, пока это событие не завершится.
ApplicationStopping Происходит нормальное завершение работы узла. Запросы могут все еще обрабатываться. Завершение работы блокируется до тех пор, пока это событие не завершится.
public class Startup
{
    public void Configure(IApplicationBuilder app, IApplicationLifetime 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 IApplicationLifetime _appLifetime;

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

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

Проверка области

CreateDefaultBuilder устанавливает для ServiceProviderOptions.ValidateScopes значение true, если приложение находится в среде разработки.

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

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

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

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

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

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

Дополнительные ресурсы