"
ASP.NET (snapshot 2017) Microsoft documentation and samples

Application startup in ASP.NET Core

By Steve Smith, Tom Dykstra, and Luke Latham

The Startup class configures services and the app’s request pipeline.

The Startup class

ASP.NET Core apps use a Startup class, which is named Startup by convention. The Startup class:

ConfigureServices and Configure are called by the runtime when the app starts:

[!code-csharpMain]

   1:  public class Startup
   2:  {
   3:      // Use this method to add services to the container.
   4:      public void ConfigureServices(IServiceCollection services)
   5:      {
   6:          ...
   7:      }
   8:   
   9:      // Use this method to configure the HTTP request pipeline.
  10:      public void Configure(IApplicationBuilder app)
  11:      {
  12:          ...
  13:      }
  14:  }

Specify the Startup class with the WebHostBuilderExtensions UseStartup<TStartup> method:

[!code-csharpMain]

   1:  using System;
   2:  using System.Collections.Generic;
   3:  using System.IO;
   4:  using System.Linq;
   5:  using System.Threading.Tasks;
   6:  using Microsoft.AspNetCore;
   7:  using Microsoft.AspNetCore.Hosting;
   8:  using Microsoft.Extensions.Configuration;
   9:  using Microsoft.Extensions.Logging;
  10:   
  11:  namespace WebApplication1
  12:  {
  13:      #region snippet_Main
  14:      public class Program
  15:      {
  16:          public static void Main(string[] args)
  17:          {
  18:              BuildWebHost(args).Run();
  19:          }
  20:   
  21:          public static IWebHost BuildWebHost(string[] args) =>
  22:              WebHost.CreateDefaultBuilder(args)
  23:                  .UseStartup<Startup>()
  24:                  .Build();
  25:      }
  26:      #endregion
  27:  }

The Startup class constructor accepts dependencies defined by the host. A common use of (xref:)dependency injection into the Startup class is to inject IHostingEnvironment to configure services by environment:

[!code-csharpMain]

   1:  public class Startup
   2:  {
   3:      public Startup(IHostingEnvironment env)
   4:      {
   5:          HostingEnvironment = env;
   6:      }
   7:   
   8:      public IHostingEnvironment HostingEnvironment { get; }
   9:   
  10:      public void ConfigureServices(IServiceCollection services)
  11:      {
  12:          if (HostingEnvironment.IsDevelopment())
  13:          {
  14:              // Development configuration
  15:          }
  16:          else
  17:          {
  18:              // Staging/Production configuration
  19:          }
  20:      }
  21:  }

An alternative to injecting IHostingStartup is to use a conventions-based approach. The app can define separate Startup classes for different environments (for example, StartupDevelopment), and the appropriate startup class is selected at runtime. The class whose name suffix matches the current environment is prioritized. 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 (xref:)Working with multiple environments.

To learn more about WebHostBuilder, see the (xref:)Hosting topic. For information on handling errors during startup, see (xref:)Startup exception handling.

The ConfigureServices method

The ConfigureServices method is:

Adding services to the service container makes them available within the app and in the Configure method. The services are resolved via (xref:)dependency injection or from IApplicationBuilder.ApplicationServices.

The web host may configure some services before Startup methods are called. Details are available in the (xref:)Hosting topic.

For features that require substantial setup, there are Add[Service] extension methods on IServiceCollection. A typical web app registers services for Entity Framework, Identity, and MVC:

[!code-csharpMain]

   1:  using System;
   2:  using System.Collections.Generic;
   3:  using System.Linq;
   4:  using System.Threading.Tasks;
   5:  using Microsoft.AspNetCore.Builder;
   6:  using Microsoft.AspNetCore.Hosting;
   7:  using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
   8:  using Microsoft.EntityFrameworkCore;
   9:  using Microsoft.Extensions.Configuration;
  10:  using Microsoft.Extensions.DependencyInjection;
  11:  using Microsoft.Extensions.Logging;
  12:  using WebApplication1.Data;
  13:  using WebApplication1.Models;
  14:  using WebApplication1.Services;
  15:   
  16:  namespace WebApplication1
  17:  {
  18:      public class Startup
  19:      {
  20:          public Startup(IHostingEnvironment env)
  21:          {
  22:              var builder = new ConfigurationBuilder()
  23:                  .SetBasePath(env.ContentRootPath)
  24:                  .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
  25:                  .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);
  26:   
  27:              if (env.IsDevelopment())
  28:              {
  29:                  // For more details on using the user secret store see http://go.microsoft.com/fwlink/?LinkID=532709
  30:                  builder.AddUserSecrets<Startup>();
  31:              }
  32:   
  33:              builder.AddEnvironmentVariables();
  34:              Configuration = builder.Build();
  35:          }
  36:   
  37:          public IConfigurationRoot Configuration { get; }
  38:   
  39:          // This method gets called by the runtime. Use this method to add services to the container.
  40:          public void ConfigureServices(IServiceCollection services)
  41:          {
  42:              // Add framework services.
  43:              services.AddDbContext<ApplicationDbContext>(options =>
  44:                  options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
  45:   
  46:              services.AddIdentity<ApplicationUser, IdentityRole>()
  47:                  .AddEntityFrameworkStores<ApplicationDbContext>()
  48:                  .AddDefaultTokenProviders();
  49:   
  50:              services.AddMvc();
  51:   
  52:              // Add application services.
  53:              services.AddTransient<IEmailSender, AuthMessageSender>();
  54:              services.AddTransient<ISmsSender, AuthMessageSender>();
  55:          }
  56:   
  57:          // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
  58:          public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
  59:          {
  60:              loggerFactory.AddConsole(Configuration.GetSection("Logging"));
  61:              loggerFactory.AddDebug();
  62:   
  63:              if (env.IsDevelopment())
  64:              {
  65:                  app.UseDeveloperExceptionPage();
  66:                  app.UseDatabaseErrorPage();
  67:                  app.UseBrowserLink();
  68:              }
  69:              else
  70:              {
  71:                  app.UseExceptionHandler("/Home/Error");
  72:              }
  73:   
  74:              app.UseStaticFiles();
  75:   
  76:              app.UseIdentity();
  77:   
  78:              app.UseMvc(routes =>
  79:              {
  80:                  routes.MapRoute(
  81:                      name: "default",
  82:                      template: "{controller=Home}/{action=Index}/{id?}");
  83:              });
  84:          }
  85:      }
  86:  }

Services available in Startup

The web host provides some services that are available to the Startup class constructor. The app adds additional services via ConfigureServices. Both the host and app services are then available in Configure and throughout the application.

The Configure method

The Configure method is used to specify how the app responds to HTTP requests. The request pipeline is configured by adding (xref:)middleware components to an IApplicationBuilder instance. IApplicationBuilder is available to the Configure method, but it isn’t registered in the service container. Hosting creates an IApplicationBuilder and passes it directly to Configure (reference source).

The ASP.NET Core templates configure the pipeline with support for a developer exception page, BrowserLink, error pages, static files, and ASP.NET MVC:

[!code-csharpMain]

   1:  using System;
   2:  using System.Collections.Generic;
   3:  using System.Linq;
   4:  using System.Threading.Tasks;
   5:  using Microsoft.AspNetCore.Builder;
   6:  using Microsoft.AspNetCore.Hosting;
   7:  using Microsoft.Extensions.Configuration;
   8:  using Microsoft.Extensions.DependencyInjection;
   9:   
  10:  namespace WebApplication1
  11:  {
  12:      public class Startup
  13:      {
  14:          public Startup(IConfiguration configuration)
  15:          {
  16:              Configuration = configuration;
  17:          }
  18:   
  19:          public IConfiguration Configuration { get; }
  20:   
  21:          // This method gets called by the runtime. Use this method to add services to the container.
  22:          public void ConfigureServices(IServiceCollection services)
  23:          {
  24:              services.AddMvc();
  25:          }
  26:   
  27:          // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
  28:          public void Configure(IApplicationBuilder app, IHostingEnvironment env)
  29:          {
  30:              if (env.IsDevelopment())
  31:              {
  32:                  app.UseDeveloperExceptionPage();
  33:                  app.UseBrowserLink();
  34:              }
  35:              else
  36:              {
  37:                  app.UseExceptionHandler("/Error");
  38:              }
  39:   
  40:              app.UseStaticFiles();
  41:   
  42:              app.UseMvc(routes =>
  43:              {
  44:                  routes.MapRoute(
  45:                      name: "default",
  46:                      template: "{controller}/{action=Index}/{id?}");
  47:              });
  48:          }
  49:      }
  50:  }

Each Use extension method adds a middleware component to the request pipeline. For instance, the UseMvc extension method adds the (xref:)routing middleware to the request pipeline and configures (xref:)MVC as the default handler.

Additional services, such as IHostingEnvironment and ILoggerFactory, may also be specified in the method signature. When specified, additional services are injected if they’re available.

For more information on how to use IApplicationBuilder, see (xref:)Middleware.

Convenience methods

ConfigureServices and Configure convenience methods can be used instead of specifying a Startup class. Multiple calls to ConfigureServices append to one another. Multiple calls to Configure use the last method call.

[!code-csharpMain]

   1:  public class Program
   2:  {
   3:      public static IHostingEnvironment HostingEnvironment { get; set; }
   4:   
   5:      public static void Main(string[] args)
   6:      {
   7:          BuildWebHost(args).Run();
   8:      }
   9:   
  10:      public static IWebHost BuildWebHost(string[] args) =>
  11:          WebHost.CreateDefaultBuilder(args)
  12:              .ConfigureAppConfiguration((hostingContext, config) =>
  13:              {
  14:                  HostingEnvironment = hostingContext.HostingEnvironment;
  15:              })
  16:              .ConfigureServices(services =>
  17:              {
  18:                  services.AddMvc();
  19:              })
  20:              .Configure(app =>
  21:              {
  22:                  if (HostingEnvironment.IsDevelopment())
  23:                  {
  24:                      app.UseDeveloperExceptionPage();
  25:                  }
  26:                  else
  27:                  {
  28:                      app.UseExceptionHandler("/Error");
  29:                  }
  30:   
  31:                  app.UseMvcWithDefaultRoute();
  32:                  app.UseStaticFiles();
  33:              })
  34:              .Build();
  35:  }

Startup filters

Use IStartupFilter to configure middleware at the beginning or end of an app’s Configure middleware pipeline. 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 implements a single method, Configure, which receives and returns an Action<IApplicationBuilder>. An IApplicationBuilder defines a class to configure an app’s request pipeline. For more information, see (xref:)Creating a middleware pipeline with IApplicationBuilder.

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.

The sample app ((xref:)how to download) demonstrates how to register a middleware with IStartupFilter. The sample app includes a middleware that sets an options value from a query string parameter:

[!code-csharpMain]

   1:  using System;
   2:  using System.Net;
   3:  using System.Threading.Tasks;
   4:  using Microsoft.AspNetCore.Http;
   5:  using Microsoft.Extensions.Options;
   6:  using StartupFilterSample.Models;
   7:   
   8:  namespace StartupFilterSample
   9:  {
  10:      #region snippet1
  11:      public class RequestSetOptionsMiddleware
  12:      {
  13:          private readonly RequestDelegate _next;
  14:          private IOptions<AppOptions> _injectedOptions;
  15:   
  16:          public RequestSetOptionsMiddleware(
  17:              RequestDelegate next, IOptions<AppOptions> injectedOptions)
  18:          {
  19:              _next = next;
  20:              _injectedOptions = injectedOptions;
  21:          }
  22:   
  23:          public async Task Invoke(HttpContext httpContext)
  24:          {
  25:              Console.WriteLine("RequestSetOptionsMiddleware.Invoke");
  26:   
  27:              var option = httpContext.Request.Query["option"];
  28:   
  29:              if (!string.IsNullOrWhiteSpace(option))
  30:              {
  31:                  _injectedOptions.Value.Option = WebUtility.HtmlEncode(option);
  32:              }
  33:   
  34:              await _next(httpContext);
  35:          }
  36:      }
  37:      #endregion
  38:  }

The RequestSetOptionsMiddleware is configured in the RequestSetOptionsStartupFilter class:

[!code-csharpMain]

   1:  using System;
   2:  using Microsoft.AspNetCore.Builder;
   3:  using Microsoft.AspNetCore.Hosting;
   4:   
   5:  namespace StartupFilterSample
   6:  {
   7:      #region snippet1
   8:      public class RequestSetOptionsStartupFilter : IStartupFilter
   9:      {
  10:          public Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next)
  11:          {
  12:              return builder =>
  13:              {
  14:                  builder.UseMiddleware<RequestSetOptionsMiddleware>();
  15:                  next(builder);
  16:              };
  17:          }
  18:      }
  19:      #endregion
  20:  }

The IStartupFilter is registered in the service container in ConfigureServices:

[!code-csharpMain]

   1:  using Microsoft.AspNetCore.Builder;
   2:  using Microsoft.AspNetCore.Hosting;
   3:  using Microsoft.Extensions.DependencyInjection;
   4:   
   5:  namespace StartupFilterSample
   6:  {
   7:      public class Startup
   8:      {
   9:          #region snippet1
  10:          public void ConfigureServices(IServiceCollection services)
  11:          {
  12:              services.AddTransient<IStartupFilter, RequestSetOptionsStartupFilter>();
  13:              services.AddMvc();
  14:          }
  15:          #endregion
  16:   
  17:          public void Configure(IApplicationBuilder app, IHostingEnvironment env)
  18:          {
  19:              if (env.IsDevelopment())
  20:              {
  21:                  app.UseDeveloperExceptionPage();
  22:              }
  23:              else
  24:              {
  25:                  app.UseExceptionHandler("/Error");
  26:              }
  27:   
  28:              app.UseStaticFiles();
  29:              app.UseMvc();
  30:          }
  31:      }
  32:  }

When a query string parameter for option is provided, the middleware processes the value assignment before the MVC middleware renders the response:

Browser window showing the rendered Index page. The value of Option is rendered as ‘From Middleware’ based on requesting the page with the query string parameter and value of option set to ‘From Middleware’.
Browser window showing the rendered Index page. The value of Option is rendered as ‘From Middleware’ based on requesting the page with the query string parameter and value of option set to ‘From Middleware’.

Middleware execution order is set by the order of IStartupFilter registrations:

Additional resources



Comments ( )
Link to this page: //www.vb-net.com/AspNet-DocAndSamples-2017/aspnetcore/fundamentals/startup.htm
< THANKS ME>