asp.net core 系列之Startup
这篇文章简单记录 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<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类中,一种依赖注入的常见用法:
- 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<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 , 当定义不同环境的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<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 模板 配置的管道:
- 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<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);
}
}
RequestSetOptionsMiddleware 中间件被配置在 RequestSetOptionsStartupFilter 类中:
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 解析services的使用
IApplicationBuilder app
app.ApplicationServices.GetService 方法
如上,IApplicationBuilder类型,即可得到ApplicationServices,然后利用其方法来解析services
参考网址:
https://docs.microsoft.com/en-us/aspnet/core/fundamentals/startup?view=aspnetcore-2.2
asp.net core 系列之Startup的更多相关文章
- ASP.NET Core系列(三):启动类Startup
前面讲了ASP.NET Core 的项目结构,查看完整的ASP.NET Core系列文章:https://www.cnblogs.com/zhangweizhong/category/1477144. ...
- asp.net core系列 30 EF管理数据库架构--必备知识 迁移
一.管理数据库架构概述 EF Core 提供两种主要方法来保持 EF Core 模型和数据库架构同步.一是以 EF Core 模型为基准,二是以数据库为基准. (1)如果希望以 EF Core 模型为 ...
- asp.net core系列 39 Web 应用Razor 介绍与详细示例
一. Razor介绍 在使用ASP.NET Core Web开发时, ASP.NET Core MVC 提供了一个新特性Razor. 这样开发Web包括了MVC框架和Razor框架.对于Razor来说 ...
- asp.net core系列 38 WebAPI 返回类型与响应格式--必备
一.返回类型 ASP.NET Core 提供以下 Web API Action方法返回类型选项,以及说明每种返回类型的最佳适用情况: (1) 固定类型 (2) IActionResult (3) Ac ...
- asp.net core 系列 22 EF(连接字符串,连接复原,DbContext)
一.连接字符串 在上二篇中,ASP.NET Core 应用程序连接字符串是写死在ConfigureServices代码中,下面介绍通过配置来实现.连接字符串可以存储在 appsettings.json ...
- asp.net core 系列 18 web服务器实现
一. ASP.NET Core Module 在介绍ASP.NET Core Web实现之前,先来了解下ASP.NET Core Module.该模块是插入 IIS 管道的本机 IIS 模块(本机是指 ...
- asp.net core 系列 16 Web主机 IWebHostBuilder
一.概述 在asp.net core中,Host主机负责应用程序启动和生存期管理.host主机包括Web 主机(IWebHostBuilder)和通用主机(IHostBuilder).Web 主机是适 ...
- asp.net core 系列 14 错误处理
一.概述 本文介绍处理 ASP.NET Core 应用中常见错误的一些方法.主要是关于:开发环境异常页:非开发环境配置自定义异常处理页:配置状态代码页(没有正文响应,http状态400~599的). ...
- 技术的正宗与野路子 c#, AOP动态代理实现动态权限控制(一) 探索基于.NET下实现一句话木马之asmx篇 asp.net core 系列 9 环境(Development、Staging 、Production)
黄衫女子的武功似乎与周芷若乃是一路,飘忽灵动,变幻无方,但举手抬足之间却是正而不邪,如说周芷若形似鬼魅,那黄衫女子便是态拟神仙. 这段描写出自<倚天屠龙记>第三十八回. “九阴神抓”本是& ...
随机推荐
- Android官方教程翻译(2)——运行第一个程序
转载请注明出处:http://blog.csdn.net/dawanganban/article/details/9823623 Running Your App PREVIOUSNEXT THIS ...
- 贝叶斯方法(Bayesian approach) —— 一种概率解释(probabilistic interpretation)
1. Bayesian approach 对于多项式拟合问题,我们可通过最小二乘(least squares)的方式计算得到模型的参数,最小二乘法又可视为最大似然(maximum likelihood ...
- 《用户体验要素》澄清了 UI 原型设计中看不见确感受得到的那一层
<用户体验要素>澄清了看不见确感受得到的那一层 太阳火神的漂亮人生 (http://blog.csdn.net/opengl_es) 本文遵循"署名-非商业用途-保持一致&quo ...
- “warning C4996: 'fopen': This function or variable may be unsafe”和“LINK : fatal error LNK1104”的解决办法
程序有时编译出现警告C4996,报错: warning C4996: 'fopen': This function or variable may be unsafe. Consider using ...
- 去除WPF中3D图形的锯齿
原文:去除WPF中3D图形的锯齿 理论上讲PC在计算3D图形的时候是无法避免不出现锯齿的,因为3D图形都是又若干个三角形组成,如果3D图形想平滑就必须建立多个三角形,你可以想象一下正5边形和正100边 ...
- C++学习笔记26,虚函数
在C++里面,虚拟功能是功能的一类重要!不同目的可以通过在不同的虚拟功能来达到同样的动作被定义. 举一个简单的例子: #include <iostream> #include <st ...
- matlab 稀疏矩阵(sparse matrix)
参数的设置:spparms() spparms('spumoni', 3);:Set sparse monitor flag to obtain diagnostic output 1. 创建稀疏矩阵 ...
- Java Swing编程接口(30)---列表框:JList
列表框同时可以在信息呈现给用户的列表多个选项,使用JList能够建立一个列表框. package com.beyole.util; import java.awt.Container; import ...
- eclipse 配置maven tomcat 环境
一 maven配置文件路径 二 tomcat 和JRE位置 三 validation 设置 四 五 六 设置run(debug) configurations 七 添加server时添加 reso ...
- NSURLSession 网络库 - 原生系统送给我们的礼物
大家在进行iOS开发的时候一定会用到网络操作.但由于早期原生的 NSURLConnection 操作起来有很多不便,使得大家更愿意使用第三方库的解决方案,比如鼎鼎大名的 AFNetworking.正是 ...