ASP.NET Core 中的应用程序启动

ASP.NET Core 中的应用程序启动

Startup 类配置服务和应用的请求管道。

Startup 类

ASP.NET Core 应用使用 Startup 类,按照约定命名为 StartupStartup 类:

  • 可选择性地包括 ConfigureServices 方法以配置应用的服务。
  • 必须包括 Configure 方法以创建应用的请求处理管道。

当应用启动时,运行时调用 ConfigureServicesConfigure

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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)
{
...
}
}

通过 WebHostBuilderExtensions、UseStartup<TStartup> 方法指定 Startup 类:

1
2
3
4
5
6
7
8
9
10
11
12
public class Program
{
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.Build();
}

Startup 类构造函数接受由主机定义的依赖关系。 在 Startup 类中注入依赖关系的常见用途为注入:

  • IHostingEnvironment 以按环境配置服务。
  • IConfiguration 以在启动过程中配置应用。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class Startup
{
public Startup(IHostingEnvironment env, IConfiguration config)
{
HostingEnvironment = env;
Configuration = config;
}
public IHostingEnvironment HostingEnvironment { get; }
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
if (HostingEnvironment.IsDevelopment())
{
// Development configuration
}
else
{
// Staging/Production configuration
}
// Configuration is available during startup. Examples:
// Configuration["key"]
// Configuration["subsection:suboption1"]
}
}

注入 IHostingEnvironment 的替代方法是使用基于约定的方法。 该应用可以为不同的环境(例如 StartupDevelopment)定义单独的 Startup 类,并在运行时选择适当的 startup 类。 优先考虑名称后缀与当前环境相匹配的类。 如果应用在开发环境中运行并包含 Startup 类和 StartupDevelopment 类,则使用 StartupDevelopment 类。

ConfigureServices 方法

ConfigureServices 方法是:

  • Optional
  • Configure 方法配置应用服务之前,由 Web 主机调用。
  • 其中按常规设置配置选项。

将服务添加到服务容器,使其在应用和 Configure 方法中可用。 这些服务通过依赖关系注入或 IApplicationBuilder.ApplicationServices 解析。

Web 主机可能会在调用 Startup 方法之前配置某些服务。

对于需要大量设置的功能,IServiceCollection 上有 Add[Service] 扩展方法。 典型 Web 应用将为实体框架、标识和 MVC 注册服务:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
services.AddMvc();
// Add application services.
services.AddTransient<IEmailSender, AuthMessageSender>();
services.AddTransient<ISmsSender, AuthMessageSender>();
}

ASP.NET Core MVC 的 SetCompatibilityVersion

SetCompatibilityVersion 方法允许应用选择加入或退出 ASP.NET MVC Core 2.1+ 中引入的潜在中断行为变更。 这些潜在的中断行为变更通常取决于 MVC 子系统的行为方式以及运行时调用“代码”的方式。 通过选择加入,你将获取最新的行为以及 ASP.NET Core 的长期行为。

以下代码将兼容模式设置为 ASP.NET Core 2.1:

1
2
3
4
5
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}

调用 SetCompatibilityVersion(CompatibilityVersion.Version_2_0) 的应用程序会被阻止进行 ASP.NET Core 2.1 MVC 和更高的 2.x 版本中引入的潜在中断行为变更。 该阻止操作:

  • 不适用于所有 2.1 和更高版本的更改,它的目标是潜在地中断 MVC 子系统中的 ASP.NET Core 运行时行为变更。
  • 不会扩展到下一个主要版本。

不调用 SetCompatibilityVersion 的 ASP.NET Core 2.1 和更高 2.x 版本的应用程序的默认兼容性是 2.0 兼容性。 即,未调用 SetCompatibilityVersion 与调用 SetCompatibilityVersion(CompatibilityVersion.Version_2_0) 相同。

以下代码将兼容模式设置为 ASP.NET Core 2.1(以下行为除外):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc()
// Include the 2.1 behaviors
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
// Except for the following.
.AddMvcOptions(options =>
{
// Don't combine authorize filters (keep 2.0 behavior).
options.AllowCombiningAuthorizeFilters = false;
// All exceptions thrown by an IInputFormatter will be treated
// as model state errors (keep 2.0 behavior).
options.InputFormatterExceptionPolicy =
InputFormatterExceptionPolicy.AllExceptions;
});
}

对于遇到中断行为变更的应用,请使用适当的兼容性开关:

  • 允许使用最新版本并选择退出特定的中断行为变更。
  • 请用些时间更新应用,以便其适用于最新更改。

MvcOptions 类源注释充分地阐述了更改的内容以及为什么更改对大多数用户来说是一种改进。

将来会推出 ASP.NET Core 3.0 版本。 在 3.0 版本中,将删除兼容性开关支持的旧行为。

Startup 中可用的服务

Web 主机提供 Startup 类构造函数可用的某些服务。 应用通过 ConfigureServices 添加其他服务。 然后,主机和应用服务都可以在 Configure 和整个应用程序中使用。

Configure 方法

Configure 方法用于指定应用响应 HTTP 请求的方式。 可通过将中间件组件添加到 IApplicationBuilder 实例来配置请求管道。 Configure 方法可使用 IApplicationBuilder,但未在服务容器中注册。 承载创建 IApplicationBuilder 并将其直接传递给 Configure引用源)。

ASP.NET Core 模板配置支持开发人员异常页、BrowserLink、错误页、静态文件和 ASP.NET MVC 的管道:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseBrowserLink();
}
else
{
app.UseExceptionHandler("/Error");
}
app.UseStaticFiles();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller}/{action=Index}/{id?}");
});
}

每个 Use 扩展方法将中间件组件添加到请求管道。 例如,UseMvc 扩展方法将路由中间件添加到请求管道,并将 MVC 配置为默认处理程序。

请求管道中的每个中间件组件负责调用管道中的下一个组件,或在适当情况下使链发生短路。 如果中间件链中未发生短路,则每个中间件都有第二次机会在将请求发送到客户端前处理该请求。

其他服务(如 IHostingEnvironmentILoggerFactory),也可以在方法签名中指定。 如果指定,其他服务如果可用,将被注入。

便利方法

可使用 ConfigureServices 和 Configure 便利方法,而不是指定 Startup 类。 多次调用 ConfigureServices 将追加到另一个。 多次调用 Configure 将使用上一个方法调用。

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

Startup 筛选器

在应用的 Configure 中间件管道的开头或末尾使用 IStartupFilter 来配置中间件。 IStartupFilter 有助于确保中间件在应用请求处理管道的开始或结束时由库添加的中间件之前或之后运行。

IStartupFilter 实现单个方法(即 Configure),该方法接收并返回 Action<IApplicationBuilder>。 IApplicationBuilder 定义用于配置应用请求管道的类。

在请求管道中,每个 IStartupFilter 实现一个或多个中间件。 筛选器按照添加到服务容器的顺序调用。 筛选器可在将控件传递给下一个筛选器之前或之后添加中间件,从而附加到应用管道的开头或末尾。

示例应用演示如何向 IStartupFilter 注册中间件。 示例应用包含一个中间件,该中间件从查询字符串参数中设置选项值:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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);
}
}

RequestSetOptionsStartupFilter 类中配置 RequestSetOptionsMiddleware

1
2
3
4
5
6
7
8
9
10
11
public class RequestSetOptionsStartupFilter : IStartupFilter
{
public Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next)
{
return builder =>
{
builder.UseMiddleware<RequestSetOptionsMiddleware>();
next(builder);
};
}
}

ConfigureServices 的服务容器中注册 IStartupFilter

1
2
3
4
5
public void ConfigureServices(IServiceCollection services)
{
services.AddTransient<IStartupFilter, RequestSetOptionsStartupFilter>();
services.AddMvc();
}

当提供 option 的查询字符串参数时,中间件在 MVC 中间件呈现响应之前处理分配值:

浏览器窗口显示已呈现的索引页。 基于请求页面(其中查询字符串参数和选项的值设置为“From Middleware”),Option 的值呈现为“From Middleware”。

中间件执行顺序由 IStartupFilter 注册顺序设置:

  • 多个 IStartupFilter 实现可能与相同的对象进行交互。 如果顺序很重要,请将它们的 IStartupFilter 服务注册进行排序,以匹配其中间件应有的运行顺序。
  • 库可能添加包含一个或多个 IStartupFilter 实现的中间件,这些实现在向 IStartupFilter 注册的其他应用中间件之前或之后运行。 若要在库的 IStartupFilter 添加中间件之前调用 IStartupFilter 中间件,请在将库添加到服务容器之前定位服务注册。 若要在此后调用,请在添加库之后定位服务注册。

在启动时从外部程序集添加配置

通过 IHostingStartup 实现,可在启动时从应用 Startup 类之外的外部程序集向应用添加增强功能。

×

谢谢你请我吃辣条

扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

文章目录
  1. 1. ASP.NET Core 中的应用程序启动
    1. 1.1. Startup 类
    2. 1.2. ConfigureServices 方法
      1. 1.2.1. ASP.NET Core MVC 的 SetCompatibilityVersion
    3. 1.3. Startup 中可用的服务
    4. 1.4. Configure 方法
    5. 1.5. 便利方法
    6. 1.6. Startup 筛选器
    7. 1.7. 在启动时从外部程序集添加配置
,