asp.net core 系列之Startup

匿名 (未验证) 提交于 2019-12-02 23:45:01

这篇文章简单记录 ASP.NET Core中 ,startup类的一些使用。

Startup类中,一般有两个方法:

  • Configure 方法:创建应用的请求处理管道

它们都在应用启动时,被ASP.NET Core runtime 调用:

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)     {         ...     } }

当应用的 host 被built(建立)时,Startup类被指定到应用中。

而在 Program 中,当 host builder 上的 Build 被调用时,应用的 host 被 built 。

Startup类是通过调用WebHostBuilderExtensions.UseStartup<TStartup>方法指定的。

public class Program {     public static void Main(string[] args)     {         CreateWebHostBuilder(args).Build().Run(); //Build方法被调用时,应用的host被建立,同时Startup被指定到应用中     }      public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>         WebHost.CreateDefaultBuilder(args)             .UseStartup<Startup>(); }

在startup类中,一种依赖注入的常见用法:

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"]     } }

注入

二.ConfigureServices方法

它有三个特点:

  • 可选的
  • 在调用Configure方法之前调用 ConfigureServices
  • Configuration options 按约定设置

1. 比较典型的是调用 Add{Service} 和 services.Configure{Service} 。例如:Configure Identity services.

The host.

在startup被调用之前,CreateDefaultBuilder方法配置了一个host 。

3. Add{Service}是IServiceCollection的扩展方法,下面是一些使用:

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>(); }

添加 services 到 service container 使它们在应用和Configure方法中可用。services方法可以通过 dependency injection 或 ApplicationServices 解析。

三.The Configure method

Configure方法用来指定应用怎样 处理HTTP request。请求管道(request pipeline)通过添加中间组件到IApplicationBuilder实例中来配置。

ASP.NET Core 模板 配置的管道:

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扩展方法添加一个或多个中间组件到请求管道。例如,UseMvc扩展方法添加 Routing Middleware 到请求管道 并且配置MVC 作为一个默认的处理器。

四.Convenience methods

不使用Startup类配置services和request processing pipeline。在host builder 上调用ConfigureServices和Configure的简便方法。如果存在多个ConfigureServices的调用,会依次添加。如果存在多个Configure方法的调用,最后一个Configure的调用会被使用。

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"];                  ...             }); }

五.Extend Startup with startup filters (使用startup filter扩展 Startup)

使用 IStartupFilter ,在应用的Configure 中间件管道的开头或末尾配置中间件

IStartupFilter 实现Configure方法,它会接收和返回一个Action<IApplicationBuilder>。而IApplicationBuilder定义了一个类来配置一个应用的请求管道。

这些filters会按照添加到services container的顺序被调用。

下面是一个例子:

RequestSetOptionsMiddleware

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"]; //取请求中的option参数          if (!string.IsNullOrWhiteSpace(option))         {             _injectedOptions.Value.Option = WebUtility.HtmlEncode(option);         }          await _next(httpContext);     } }

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

IStartupFilter 在 ConfigureServices中被注册到 service container, 并且从Startup类的外部增强Startup:

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

当option的查询字符串存在时,中间件会在MVC中间件之前处理这个值

中间件的执行顺序是按照IStartupFilter的注册顺序

六. 补充

ApplicationServices

参考网址:

https://docs.microsoft.com/en-us/aspnet/core/fundamentals/startup?view=aspnetcore-2.2

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!