这篇文章简单记录 ASP.NET Core中 ,startup类的一些使用。
一.前言
在 Startup类中,一般有两个方法:
ConfigureServices 方法: 用来配置应用的 service 。
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方法指定的。
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类中,一种依赖注入的常见用法:
IHostingEnvironment : 根据enviironment (环境) 配置 services .
IConfiguration : 读取配置
ILoggerFactory : 在Startup.ConfigureServices中创建 logger .
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();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 , 当定义不同环境的Startup (例如,StartupDevelopment 等),在运行时,选择合适的Startup。
二.ConfigureServices方法
它有三个特点:
可选的
在调用Configure方法之前调用 ConfigureServices
Configuration options 按约定设置
1. 比较典型的是调用 Add{Service} 和 services.Configure{Service} 。例如:Configure Identity services.
2. host 可能会 在Startup方法被调用之前,配置一些服务。例如:The host.
在startup被调用之前,CreateDefaultBuilder方法配置了一个host 。
3. Add{Service}是IServiceCollection的扩展方法,下面是一些使用:
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext(options =>
options.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection")));
services.AddDefaultIdentity()
.AddDefaultUI(UIFramework.Bootstrap4)
.AddEntityFrameworkStores();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);// Add application services. 添加应用的服务
services.AddTransient();
services.AddTransient();
}
添加 services 到 service container 使它们在应用和Configure方法中可用。services方法可以通过 dependency injection 或 ApplicationServices 解析。
三.The Configure method
Configure方法用来指定应用怎样 处理HTTP request。请求管道(request pipeline)通过添加中间组件到IApplicationBuilder实例中来配置。
ASP.NET Core 模板 配置的管道:
Developer Exception Page
Exception handler
HTTP Strict Transport Security (HSTS)
HTTPS redirection
Static files
General Data Protection Regulation (GDPR)
ASP.NET Core MVC and Razor Pages
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();var logger = loggerFactory.CreateLogger();var env = app.ApplicationServices.GetRequiredServices();var config = app.ApplicationServices.GetRequiredServices();
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定义了一个类来配置一个应用的请求管道。
这些filters会按照添加到services container的顺序被调用。
下面是一个例子:
RequestSetOptionsMiddleware
public class RequestSetOptionsMiddleware
{private readonly RequestDelegate _next;private IOptions _injectedOptions;public RequestSetOptionsMiddleware(
RequestDelegate next, IOptions 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);
}
}
RequestSetOptionsMiddleware 中间件被配置在 RequestSetOptionsStartupFilter 类中:
public class RequestSetOptionsStartupFilter : IStartupFilter
{public Action Configure(Action next)
{return builder =>
{builder.UseMiddleware();
next(builder);
};
}
}
IStartupFilter 在 ConfigureServices中被注册到 service container, 并且从Startup类的外部增强Startup:
WebHost.CreateDefaultBuilder(args)
.ConfigureServices(services =>
{services.AddTransient<IStartupFilter,
RequestSetOptionsStartupFilter>();
})
.UseStartup()
.Build();
当option的查询字符串存在时,中间件会在MVC中间件之前处理这个值
中间件的执行顺序是按照IStartupFilter的注册顺序
六. 补充
这里晚上补充下 ApplicationServices 解析services的使用
参考网址:
https://docs.microsoft.com/en-us/aspnet/core/fundamentals/startup?view=aspnetcore-2.2
原文地址:https://www.cnblogs.com/Vincent-yuan/p/11105523.html
.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com