这篇文章简单记录 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类中,一种依赖注入的常见用法:

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 模板 配置的管道:

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的更多相关文章

  1. ASP.NET Core系列(三):启动类Startup

    前面讲了ASP.NET Core 的项目结构,查看完整的ASP.NET Core系列文章:https://www.cnblogs.com/zhangweizhong/category/1477144. ...

  2. asp.net core系列 30 EF管理数据库架构--必备知识 迁移

    一.管理数据库架构概述 EF Core 提供两种主要方法来保持 EF Core 模型和数据库架构同步.一是以 EF Core 模型为基准,二是以数据库为基准. (1)如果希望以 EF Core 模型为 ...

  3. asp.net core系列 39 Web 应用Razor 介绍与详细示例

    一. Razor介绍 在使用ASP.NET Core Web开发时, ASP.NET Core MVC 提供了一个新特性Razor. 这样开发Web包括了MVC框架和Razor框架.对于Razor来说 ...

  4. asp.net core系列 38 WebAPI 返回类型与响应格式--必备

    一.返回类型 ASP.NET Core 提供以下 Web API Action方法返回类型选项,以及说明每种返回类型的最佳适用情况: (1) 固定类型 (2) IActionResult (3) Ac ...

  5. asp.net core 系列 22 EF(连接字符串,连接复原,DbContext)

    一.连接字符串 在上二篇中,ASP.NET Core 应用程序连接字符串是写死在ConfigureServices代码中,下面介绍通过配置来实现.连接字符串可以存储在 appsettings.json ...

  6. asp.net core 系列 18 web服务器实现

    一. ASP.NET Core Module 在介绍ASP.NET Core Web实现之前,先来了解下ASP.NET Core Module.该模块是插入 IIS 管道的本机 IIS 模块(本机是指 ...

  7. asp.net core 系列 16 Web主机 IWebHostBuilder

    一.概述 在asp.net core中,Host主机负责应用程序启动和生存期管理.host主机包括Web 主机(IWebHostBuilder)和通用主机(IHostBuilder).Web 主机是适 ...

  8. asp.net core 系列 14 错误处理

    一.概述 本文介绍处理 ASP.NET Core 应用中常见错误的一些方法.主要是关于:开发环境异常页:非开发环境配置自定义异常处理页:配置状态代码页(没有正文响应,http状态400~599的). ...

  9. 技术的正宗与野路子 c#, AOP动态代理实现动态权限控制(一) 探索基于.NET下实现一句话木马之asmx篇 asp.net core 系列 9 环境(Development、Staging 、Production)

    黄衫女子的武功似乎与周芷若乃是一路,飘忽灵动,变幻无方,但举手抬足之间却是正而不邪,如说周芷若形似鬼魅,那黄衫女子便是态拟神仙. 这段描写出自<倚天屠龙记>第三十八回. “九阴神抓”本是& ...

随机推荐

  1. Android官方教程翻译(2)——运行第一个程序

    转载请注明出处:http://blog.csdn.net/dawanganban/article/details/9823623 Running Your App PREVIOUSNEXT THIS ...

  2. 贝叶斯方法(Bayesian approach) —— 一种概率解释(probabilistic interpretation)

    1. Bayesian approach 对于多项式拟合问题,我们可通过最小二乘(least squares)的方式计算得到模型的参数,最小二乘法又可视为最大似然(maximum likelihood ...

  3. 《用户体验要素》澄清了 UI 原型设计中看不见确感受得到的那一层

    <用户体验要素>澄清了看不见确感受得到的那一层 太阳火神的漂亮人生 (http://blog.csdn.net/opengl_es) 本文遵循"署名-非商业用途-保持一致&quo ...

  4. “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 ...

  5. 去除WPF中3D图形的锯齿

    原文:去除WPF中3D图形的锯齿 理论上讲PC在计算3D图形的时候是无法避免不出现锯齿的,因为3D图形都是又若干个三角形组成,如果3D图形想平滑就必须建立多个三角形,你可以想象一下正5边形和正100边 ...

  6. C++学习笔记26,虚函数

    在C++里面,虚拟功能是功能的一类重要!不同目的可以通过在不同的虚拟功能来达到同样的动作被定义. 举一个简单的例子: #include <iostream> #include <st ...

  7. matlab 稀疏矩阵(sparse matrix)

    参数的设置:spparms() spparms('spumoni', 3);:Set sparse monitor flag to obtain diagnostic output 1. 创建稀疏矩阵 ...

  8. Java Swing编程接口(30)---列表框:JList

    列表框同时可以在信息呈现给用户的列表多个选项,使用JList能够建立一个列表框. package com.beyole.util; import java.awt.Container; import ...

  9. eclipse 配置maven tomcat 环境

    一  maven配置文件路径 二  tomcat 和JRE位置 三 validation 设置 四 五 六 设置run(debug) configurations 七 添加server时添加 reso ...

  10. NSURLSession 网络库 - 原生系统送给我们的礼物

    大家在进行iOS开发的时候一定会用到网络操作.但由于早期原生的 NSURLConnection 操作起来有很多不便,使得大家更愿意使用第三方库的解决方案,比如鼎鼎大名的 AFNetworking.正是 ...