Запуск приложения в ASP.NET CoreApp startup in ASP.NET Core

Авторы: Том Дикстра (Tom Dykstra), Люк Лэтем (Luke Latham) и Стив Смит (Steve Smith)By Tom Dykstra, Luke Latham, and Steve Smith

Класс Startup настраивает службы и конвейер запросов приложения.The Startup class configures services and the app's request pipeline.

Класс StartupThe Startup class

Приложения ASP.NET Core используют класс Startup, который по соглашению называется Startup.ASP.NET Core apps use a Startup class, which is named Startup by convention. Класс Startup:The Startup class:

  • При необходимости содержит метод ConfigureServices для настройки служб приложения.Optionally includes a ConfigureServices method to configure the app's services. Служба — многократно используемый компонент, обеспечивающий функциональность приложения.A service is a reusable component that provides app functionality. Службы настраиваются — или регистрируются—в ConfigureServices и используются в приложениях с помощью внедрения зависимостей (DI) или ApplicationServices.Services are configured—also described as registered—in ConfigureServices and consumed across the app via dependency injection (DI) or ApplicationServices.
  • Содержит метод Configure для создания конвейера обработки запросов приложения.Includes a Configure method to create the app's request processing pipeline.

ConfigureServices и Configure вызываются средой выполнения ASP.NET Core при запуске приложения:ConfigureServices and Configure are called by the ASP.NET Core runtime when the app starts:

public class Startup
{
    // Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        ...
    }

    // Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app)
    {
        ...
    }
}

Класс Startup указывается в приложении при создании узла приложения.The Startup class is specified to the app when the app's host is built. Узел приложения создается при вызове Build в построителе узлов в классе Program.The app's host is built when Build is called on the host builder in the Program class. Класс Startup обычно указывается путем вызова метода WebHostBuilderExtensions.UseStartup<TStartup > в построителе узлов.The Startup class is usually specified by calling the WebHostBuilderExtensions.UseStartup<TStartup> method on the host builder:

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

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

Узел предоставляет службы, которые доступны конструктору классов Startup.The host provides services that are available to the Startup class constructor. Приложение добавляет дополнительные службы через ConfigureServices.The app adds additional services via ConfigureServices. Как службы узла, так и службы приложения доступны в Configure и во всем приложении.Both the host and app services are then available in Configure and throughout the app.

Типичным применением внедрения зависимостей в класс Startup является внедрение:A common use of dependency injection into the Startup class is to inject:

public class Startup
{
    private readonly IHostingEnvironment _env;
    private readonly IConfiguration _config;
    private readonly ILoggerFactory _loggerFactory;

    public Startup(IHostingEnvironment env, IConfiguration config, 
        ILoggerFactory loggerFactory)
    {
        _env = env;
        _config = config;
        _loggerFactory = loggerFactory;
    }

    public void ConfigureServices(IServiceCollection services)
    {
        var logger = _loggerFactory.CreateLogger<Startup>();

        if (_env.IsDevelopment())
        {
            // Development service configuration

            logger.LogInformation("Development environment");
        }
        else
        {
            // Non-development service configuration

            logger.LogInformation($"Environment: {_env.EnvironmentName}");
        }

        // Configuration is available during startup.
        // Examples:
        //   _config["key"]
        //   _config["subsection:suboption1"]
    }
}

Альтернативой внедрению IHostingEnvironment является использование подхода на основе соглашений.An alternative to injecting IHostingEnvironment is to use a conventions-based approach. Когда приложение определяет отдельные классы Startup для различных сред (например, StartupDevelopment), подходящий класс Startup выбирается во время выполнения.When the app defines separate Startup classes for different environments (for example, StartupDevelopment), the appropriate Startup class is selected at runtime. Класс, у которого суффикс имени соответствует текущей среде, получает приоритет.The class whose name suffix matches the current environment is prioritized. Если приложение выполняется в среде разработки и включает в себя оба класса — Startup и StartupDevelopment, используется класс StartupDevelopment.If the app is run in the Development environment and includes both a Startup class and a StartupDevelopment class, the StartupDevelopment class is used. Дополнительные сведения см. в статье Использование нескольких сред.For more information, see Use multiple environments.

Дополнительные сведения об узле см. в статье Узел.To learn more about the host, see The host. Сведения об обработке ошибок во время запуска см. в разделе Обработка исключений при запуске.For information on handling errors during startup, see Startup exception handling.

Метод ConfigureServicesThe ConfigureServices method

Метод ConfigureServices:The ConfigureServices method is:

  • Необязательный параметр.Optional.
  • Вызывается узлом перед методом Configure для настройки служб приложения.Called by the host before the Configure method to configure the app's services.
  • По соглашению используется для задания параметров конфигурации.Where configuration options are set by convention.

По стандартному шаблону сначала вызываются все методы Add{Service}, а затем все методы services.Configure{Service}.The typical pattern is to call all the Add{Service} methods and then call all of the services.Configure{Service} methods. Пример см. в разделе Настройка служб удостоверений.For example, see Configure Identity services.

Узел может настраивать некоторые службы перед вызовом методов Startup.The host may configure some services before Startup methods are called. Дополнительную информацию см. в разделе Узел.For more information, see The host.

Для функций, нуждающихся в значительной настройке, существуют методы расширения Add{Service} в IServiceCollection.For features that require substantial setup, there are Add{Service} extension methods on IServiceCollection. Обычное приложение ASP.NET Core регистрирует службы для Entity Framework, удостоверения и MVC:A typical ASP.NET Core app registers services for Entity Framework, Identity, and MVC:

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlServer(
            Configuration.GetConnectionString("DefaultConnection")));
    services.AddDefaultIdentity<IdentityUser>()
        .AddDefaultUI(UIFramework.Bootstrap4)
        .AddEntityFrameworkStores<ApplicationDbContext>();


    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

    // Add application services.
    services.AddTransient<IEmailSender, AuthMessageSender>();
    services.AddTransient<ISmsSender, AuthMessageSender>();
}

Добавление служб в контейнер служб делает их доступными в приложении и в методе Configure.Adding services to the service container makes them available within the app and in the Configure method. Службы разрешаются посредством внедрения зависимостей или из ApplicationServices.The services are resolved via dependency injection or from ApplicationServices.

Подробнее о SetCompatibilityVersion см. в сведениях о SetCompatibilityVersion.See SetCompatibilityVersion for more information on SetCompatibilityVersion.

Метод Configure The Configure method

Метод Configure используется для указания того, как приложение реагирует на HTTP-запросы.The Configure method is used to specify how the app responds to HTTP requests. Конвейер запросов настраивается путем добавления компонентов ПО промежуточного слоя в экземпляр IApplicationBuilder.The request pipeline is configured by adding middleware components to an IApplicationBuilder instance. IApplicationBuilder доступен для метода Configure, но он не зарегистрирован в контейнере службы.IApplicationBuilder is available to the Configure method, but it isn't registered in the service container. При размещении создается IApplicationBuilder и передается непосредственно в Configure.Hosting creates an IApplicationBuilder and passes it directly to Configure.

Шаблоны ASP.NET Core настраивают конвейер с поддержкой следующих компонентов и функций:The ASP.NET Core templates configure the pipeline with support for:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Error");
        app.UseHsts();
    }

    app.UseHttpsRedirection();
    app.UseStaticFiles();
    app.UseCookiePolicy();

    app.UseMvc();
}

Каждый метод расширения Use добавляет один или несколько компонентов ПО промежуточного слоя в конвейер запросов.Each Use extension method adds one or more middleware components to the request pipeline. Например, метод расширения UseMvc добавляет в конвейер запросов ПО промежуточного слоя для маршрутизации и настраивает MVC в качестве обработчика по умолчанию.For instance, the UseMvc extension method adds Routing Middleware to the request pipeline and configures MVC as the default handler.

Каждый компонент ПО промежуточного слоя в конвейере запросов отвечает за вызов следующего компонента в конвейере или замыкает цепочку, если это необходимо.Each middleware component in the request pipeline is responsible for invoking the next component in the pipeline or short-circuiting the chain, if appropriate. Если замыкание в цепочке ПО промежуточного слоя не происходит, у каждого ПО промежуточного слоя есть еще один шанс обработать запрос перед отправкой клиенту.If short-circuiting doesn't occur along the middleware chain, each middleware has a second chance to process the request before it's sent to the client.

В сигнатуре метода Configure также могут быть указаны дополнительные службы, такие как IHostingEnvironment и ILoggerFactory.Additional services, such as IHostingEnvironment and ILoggerFactory, may also be specified in the Configure method signature. Когда дополнительные службы указаны, они внедряются, если доступны.When specified, additional services are injected if they're available.

Дополнительные сведения об использовании IApplicationBuilder и порядке обработки ПО промежуточного слоя см. в статье ПО промежуточного слоя ASP.NET Core.For more information on how to use IApplicationBuilder and the order of middleware processing, see ПО промежуточного слоя ASP.NET Core.

Удобный методConvenience methods

Для настройки служб и конвейера обработки запросов в построителе узлов вместо класса Startup можно использовать удобные методы ConfigureServices и Configure.To configure services and the request processing pipeline without using a Startup class, call ConfigureServices and Configure convenience methods on the host builder. Несколько вызовов ConfigureServices добавляются друг к другу.Multiple calls to ConfigureServices append to one another. При наличии нескольких вызовов метода Configure используется последний вызов Configure.If multiple Configure method calls exist, the last Configure call is used.

public class Program
{
    public static IHostingEnvironment HostingEnvironment { get; set; }
    public static IConfiguration Configuration { get; set; }

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

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
            })
            .ConfigureServices(services =>
            {
                ...
            })
            .Configure(app =>
            {
                var loggerFactory = app.ApplicationServices
                    .GetRequiredService<ILoggerFactory>();
                var logger = loggerFactory.CreateLogger<Program>();
                var env = app.ApplicationServices.GetRequiredServices<IHostingEnvironment>();
                var config = app.ApplicationServices.GetRequiredServices<IConfiguration>();

                logger.LogInformation("Logged in Configure");

                if (env.IsDevelopment())
                {
                    ...
                }
                else
                {
                    ...
                }

                var configValue = config["subsection:suboption1"];

                ...
            });
}

Расширение класса Startup с использованием фильтров запускаExtend Startup with startup filters

Используйте IStartupFilter для настройки ПО промежуточного слоя в начале или конце конвейера ПО промежуточного слоя Configure приложения.Use IStartupFilter to configure middleware at the beginning or end of an app's Configure middleware pipeline. IStartupFilter удобно использовать, чтобы обеспечить запуск ПО промежуточного слоя до или после ПО промежуточного слоя, добавляемого библиотеками в начале или в конце конвейера обработки запросов приложения.IStartupFilter is useful to ensure that a middleware runs before or after middleware added by libraries at the start or end of the app's request processing pipeline.

IStartupFilter реализует отдельный метод Configure, который принимает и возвращает Action<IApplicationBuilder>.IStartupFilter implements a single method, Configure, which receives and returns an Action<IApplicationBuilder>. IApplicationBuilder определяет класс для настройки конвейера запросов приложения.An IApplicationBuilder defines a class to configure an app's request pipeline. Дополнительные сведения см. в разделе Создание конвейера ПО промежуточного слоя с помощью IApplicationBuilder.For more information, see Create a middleware pipeline with IApplicationBuilder.

Каждый IStartupFilter реализует один или несколько компонентов ПО промежуточного слоя в конвейере запросов.Each IStartupFilter implements one or more middlewares in the request pipeline. Фильтры вызываются в том порядке, в котором они были добавлены в контейнер службы.The filters are invoked in the order they were added to the service container. Фильтры могут добавлять ПО промежуточного слоя до или после передачи управления следующему фильтру, поэтому они добавляются в начало или конец конвейера приложения.Filters may add middleware before or after passing control to the next filter, thus they append to the beginning or end of the app pipeline.

В следующем примере показана регистрация ПО промежуточного слоя с помощью IStartupFilter.The following example demonstrates how to register a middleware with IStartupFilter.

ПО промежуточного слоя RequestSetOptionsMiddleware задает значения параметров из параметра строки запроса:The RequestSetOptionsMiddleware middleware sets an options value from a query string parameter:

public class RequestSetOptionsMiddleware
{
    private readonly RequestDelegate _next;
    private IOptions<AppOptions> _injectedOptions;

    public RequestSetOptionsMiddleware(
        RequestDelegate next, IOptions<AppOptions> injectedOptions)
    {
        _next = next;
        _injectedOptions = injectedOptions;
    }

    public async Task Invoke(HttpContext httpContext)
    {
        Console.WriteLine("RequestSetOptionsMiddleware.Invoke");

        var option = httpContext.Request.Query["option"];

        if (!string.IsNullOrWhiteSpace(option))
        {
            _injectedOptions.Value.Option = WebUtility.HtmlEncode(option);
        }

        await _next(httpContext);
    }
}

RequestSetOptionsMiddleware настраивается в классе RequestSetOptionsStartupFilter:The RequestSetOptionsMiddleware is configured in the RequestSetOptionsStartupFilter class:

public class RequestSetOptionsStartupFilter : IStartupFilter
{
    public Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next)
    {
        return builder =>
        {
            builder.UseMiddleware<RequestSetOptionsMiddleware>();
            next(builder);
        };
    }
}

IStartupFilter регистрируется в контейнере службы в ConfigureServices и дополняет Startup из-за пределов класса Startup:The IStartupFilter is registered in the service container in ConfigureServices and augments Startup from outside of the Startup class:

WebHost.CreateDefaultBuilder(args)
    .ConfigureServices(services =>
    {
        services.AddTransient<IStartupFilter, 
            RequestSetOptionsStartupFilter>();
    })
    .UseStartup<Startup>()
    .Build();

Если указан параметр строки запроса для option, ПО промежуточного слоя обрабатывает присвоение значения до того, как ПО промежуточного слоя MVC отображает отклик:When a query string parameter for option is provided, the middleware processes the value assignment before the MVC middleware renders the response:

Окно обозревателя с отображаемой страницей индекса.

Порядок выполнения ПО промежуточного слоя определяется порядком регистраций IStartupFilter:Middleware execution order is set by the order of IStartupFilter registrations:

  • Несколько реализаций IStartupFilter могут взаимодействовать с одними и теми же объектами.Multiple IStartupFilter implementations may interact with the same objects. Если важен порядок, упорядочите регистрации службы IStartupFilter в соответствии с требуемым порядком выполнения ПО промежуточного слоя.If ordering is important, order their IStartupFilter service registrations to match the order that their middlewares should run.
  • Библиотеки могут добавлять ПО промежуточного слоя с одной или несколькими реализациями IStartupFilter, которые выполняются до или после другого ПО промежуточного слоя приложения, зарегистрированного с помощью IStartupFilter.Libraries may add middleware with one or more IStartupFilter implementations that run before or after other app middleware registered with IStartupFilter. Чтобы вызвать ПО промежуточного слоя IStartupFilter до ПО промежуточного слоя, добавляемого библиотекой IStartupFilter, расположите регистрацию службы до добавления библиотеки в контейнер службы.To invoke an IStartupFilter middleware before a middleware added by a library's IStartupFilter, position the service registration before the library is added to the service container. Чтобы вызвать его после этого момента, расположите регистрацию службы после добавления библиотеки.To invoke it afterward, position the service registration after the library is added.

Добавление конфигурации из внешней сборки при запускеAdd configuration at startup from an external assembly

Реализация IHostingStartup позволяет при запуске добавлять в приложение улучшения из внешней сборки вне приложения класса Startup.An IHostingStartup implementation allows adding enhancements to an app at startup from an external assembly outside of the app's Startup class. Для получения дополнительной информации см. Использование начальных сборок размещения в ASP.NET Core.For more information, see Использование начальных сборок размещения в ASP.NET Core.

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