ASP.NET Core 的启动和运行机制
ASP .NET Core 的运行机制
- Web Server: ASP.NET Core 提供两种服务器可用, 分别是 Kestrel 和 HTTP.sys (Core 1.x 中被命名为 WebListener),
- Kestrel是一个跨平台的Web服务器。
- HTTP.sys只能用在Windows系统中.
- Internet: 当需要部署在Internal Network 中并需要 Kestrel 中没有的功能(如 Windows 身份验证)时,可以选择HTTP.sys。
- IIS、Apache、Nginx: Kestrel 可以单独使用 ,也可以将其与反向代理服务器(如 IIS、Nginx 或 Apache)结合使用。 请求经这些服务器进行初步处理后转发给Kestrel(即图中虚线的可选流程).
ASP .NET Core 的启动
public class Program
{
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.Build();
}
- Main: 程序的起点. ASP .NET Core 应用程序本质上是控制台应用程序。
- CreateDefaultBuilder:创建并配置WebHostBuilder, 首先调用CreateDefaultBuilder( 如图所示, 它是一系列配置的大综合,下文做详细介绍), 进行一系列配置。
- UseStartup: 指定Startup为启动配置文件. 在Startup中, 将进行两个比较重要的工作, 服务的依赖注入和配置管道。
- ConfigureServices方法是注册服务
- Configure方法是配置管道,用来具体指定如何处理每个http请求的, 例如我们可以让这个程序知道我使用mvc来处理http请求, 那就调用app.UseMvc()这个方法就行.
- BuildWebHost:生成WebHostBuilder并进行了一系列配置之后, 通过这个WebHostBuilder来Build出一个IWebHost。
- Run:调用IWebHost的Run方法使之开始运行。
CreateDefaultBuilder
public static IWebHostBuilder CreateDefaultBuilder(string[] args)
{
var builder = new WebHostBuilder()
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.ConfigureAppConfiguration((hostingContext, config) =>
{
var env = hostingContext.HostingEnvironment;
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
if (env.IsDevelopment())
{
var appAssembly = Assembly.Load(new AssemblyName(env.ApplicationName));
if (appAssembly != null)
{
config.AddUserSecrets(appAssembly, optional: true);
}
}
config.AddEnvironmentVariables();
if (args != null)
{
config.AddCommandLine(args);
}
})
.ConfigureLogging((hostingContext, logging) =>
{
logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
logging.AddConsole();
logging.AddDebug();
})
.UseIISIntegration()
.UseDefaultServiceProvider((context, options) =>
{
options.ValidateScopes = context.HostingEnvironment.IsDevelopment();
});
return builder;
}
- UseKestrel 指定服务器使用 Kestrel,若使用HttpSys,需使用UseHttpSys。
- UseContentRoot 指定根目录
- ConfigureAppConfiguration 读取配置文件
- ConfigureLogging 配置日志处理程序
- UseIISIntegration 将应用程序配置为在 IIS 中运行。如果应用程序没有使用 IIS 作为反向代理,那么 UseIISIntegration 不会有任何效果。因此,即使应用程序在非 IIS 方案中运行,也可以安全调用这种方法。
- UseDefaultServiceProvider 设置默认的依赖注入容器。
ASP .NET Core 的管道和中间件
请求管道: 那些处理http requests并返回responses的代码组成了request pipeline(请求管道).
中间件: 我们可以使用一些程序来配置请求管道(request pipeline)以便处理requests和responses. 比如处理验证(authentication)的程序, MVC本身就是个中间件(middleware).
当接收到一个请求时,请求会交给中间件构成的中间件管道进行处理,管道就是多个中间件构成,请求从一个中间件的一端进入,从中间件的另一端出来,每个中间件都可以对HttpContext请求开始和结束进行处理.
自己写一个中间件测试下:
通过约定方法实现:
public class Floor1Middleware
{
private readonly RequestDelegate _next; public Floor1Middleware(RequestDelegate next)
{
_next = next;
} public async Task InvokeAsync(HttpContext context)
{
Console.WriteLine("Floor1Middleware In");
//Do Something
//To FloorTwoMiddleware
await _next(context);
//Do Something
Console.WriteLine("Floor1Middleware Out");
}
}
添加扩展方法:
public static class Floor1MiddlewareExtensions
{
public static IApplicationBuilder UseFloor1Middleware(this IApplicationBuilder builder)
{
return builder.UseMiddleware<Floor1Middleware>();
}
}
通过 IMiddleware 实现
public class Floor3Middleware : IMiddleware
{
public async Task InvokeAsync(HttpContext context, RequestDelegate next)
{
Console.WriteLine("Floor3Middleware In");
//Do Something
//To FloorTwoMiddleware
await next(context);
//Do Something
Console.WriteLine("Floor3Middleware Out");
}
}
public static class MiddlewareExtensions
{
public static IApplicationBuilder UseFloor3Middleware(
this IApplicationBuilder builder)
{
return builder.UseMiddleware<Floor3Middleware>();
}
}
public void ConfigureServices(IServiceCollection services)
{
services.AddTransient<Floor3Middleware>(); services.AddMvc();
}
也可以用简要的写法,直接在Startup的Configure方法中这样写:
app.Use(async (context, next) =>
{
Console.WriteLine("Floor2Middleware In"); await next.Invoke(); Console.WriteLine("Floor2Middleware Out");
});
测试中间件:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseFloor1Middleware(); app.Use(async (context, next) =>
{
Console.WriteLine("Floor2Middleware In"); await next.Invoke(); Console.WriteLine("Floor2Middleware Out");
}); if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
} app.UseStaticFiles();
app.UseCookiePolicy(); app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
运行查看输出为:
DIDemo> Floor1Middleware In
DIDemo> Floor2Middleware In
DIDemo> Floor3Middleware In
DIDemo> info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[1]
DIDemo> Route matched with {action = "Index", controller = "Home"}. Executing action DIDemo.Controllers.HomeController.Index (DIDemo)
DIDemo> info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[1]
DIDemo> Executing action method DIDemo.Controllers.HomeController.Index (DIDemo) - Validation state: Valid
DIDemo> info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[2]
DIDemo> Executed action method DIDemo.Controllers.HomeController.Index (DIDemo), returned result Microsoft.AspNetCore.Mvc.ViewResult in 0.1167ms.
DIDemo> info: Microsoft.AspNetCore.Mvc.ViewFeatures.ViewResultExecutor[1]
DIDemo> Executing ViewResult, running view Index.
DIDemo> info: Microsoft.AspNetCore.Mvc.ViewFeatures.ViewResultExecutor[4]
DIDemo> Executed ViewResult - view Index executed in 3.3508ms.
DIDemo> info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[2]
DIDemo> Executed action DIDemo.Controllers.HomeController.Index (DIDemo) in 9.5638ms
DIDemo> Floor3Middleware Out
DIDemo> Floor2Middleware Out
DIDemo> Floor1Middleware Out
参考
ASP.NET Core 的启动和运行机制的更多相关文章
- 如何在ASP.NET Core程序启动时运行异步任务(3)
原文:Running async tasks on app startup in ASP.NET Core (Part 3) 作者:Andrew Lock 译者:Lamond Lu 之前我写了两篇有关 ...
- 如何在ASP.NET Core程序启动时运行异步任务(1)
原文:Running async tasks on app startup in ASP.NET Core (Part 1) 作者:Andrew Lock 译者:Lamond Lu 背景 当我们做项目 ...
- 如何在ASP.NET Core程序启动时运行异步任务(2)
原文:Running async tasks on app startup in ASP.NET Core (Part 2) 作者:Andrew Lock 译者:Lamond Lu 在我的上一篇博客中 ...
- 在 ASP.NET Core 程序启动前运行你的代码
一.前言 在进行 Web 项目开发的过程中,可能会存在一些需要经常访问的静态数据,针对这种在程序运行过程中可能几乎不会发生变化的数据,我们可以尝试在程序运行前写入到缓存中,这样在系统后续使用时就可以直 ...
- ASP.NET CORE做的网站运行在docker实践
用VS2017 建立了 DotNet Core 2.2 的网站后,如何转移到 Docker 下运行? 下面分两种方式来实践: 1.直接手动命今行,将本机目录映射进Docker,运行网站.2.制作 Im ...
- 记一次asp.net core 在iis上运行抛出502.5错误
asp.net core 在iis上运行抛出502.5异常的部分原因以及解决方案 环境说明 已安装 .net core runtime 2.1.401 已安装 .net core windows ho ...
- 01 ASP.NET Core 3 启动过程(一)
ASP.NET Core 3 启动过程(一) 最近又忙于各种扯淡,今天来一个需求,明天又来一个需求,后天需求又变了,这可能是很多人遇到的情况.正在紧张的忙碌着,突然一个信息把所有计划打乱了," ...
- 一题多解,ASP.NET Core应用启动初始化的N种方案[下篇]
[接上篇]"天下大势,分久必合,合久必分",ASP.NET应用通过GenericWebHostService这个承载服务被整合到基于IHostBuilder/IHost的服务承载系 ...
- 微服务中的健康监测以及其在ASP.NET Core服务中实现运行状况检查
1 .什么是健康检查? 健康检查几乎就是名称暗示的.它是一种检查您的应用程序是否健康的方法.随着越来越多的应用程序转向微服务式架构,健康检查变得尤其重要(Health Check).虽然微服务架构有很 ...
随机推荐
- 算法 - 最小m段和问题
题目分析 给定n个整数组成的序列,要求将序列分割为m段,每段子序列中的数在原序列中连续排列,求使得子段和的最大值达到最小的分割方法 解题方法 状态转移方程 State[i][j]表示前i个数据分成j段 ...
- MSP430 G2553 LaunchPad设置GPIO
一. 背景知识:逻辑运算符的使用 当程序初始化时,对于复位状态有不确定性的寄存器(如PxOUT),建议采用直接赋值:其他情况下最好使用逻辑运算符修改寄存器. 直接赋值 REGISTER = 0b111 ...
- Zero Clipboard js+swf实现的复制功能使用方法
开发中经常会用到复制的功能,在 IE 下实现比较简单.但要想做到跨浏览器比较困难了.本文将介绍一个跨浏览器的库类 Zero Clipboard .它利用 Flash 进行复制,所以只要浏览器装有 Fl ...
- 对Integer类中的私有IntegerCache缓存类的一点记录
对Integer类中的私有IntegerCache缓存类的一点记录 // Integer类有内部缓存,存贮着-128 到 127. // 所以,每个使用这些数字的变量都指向同一个缓存数据 // 因此可 ...
- Ubuntu 安装java 1.8
1.下载java 1.8 地址: http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.ht ...
- ROS(URDF机器人建模)
新建功能包mbot_description 在功能包下新建文件config,launch,meshes,urdf. 在launch文件夹下新建文件display_mbot_base_urdf.laun ...
- memcache内存存储
memcache的内存分配默认是采用了Slab Allocator的机制分配.管理内存.在该机制出现以前,内存的分配是通过对所有记录简单地进行malloc和free来进行的. 但是,这种方式会导致内存 ...
- C++中运算符的优先级
运算符挺多的,很难一一记住他们的优先级,在此去别人博客复制以下内容,供自己以后学习. 优先级 运算符 含 义 要求运算 对象的个数 结合方向 1 () [] -> . 圆括号 下标运算符 ...
- java使用Redis2--保存对象
Redis中并没有提供set(String key, Object obj)的方法,但提供了set(final byte[] key, final byte[] value) 的方法,可以通过把对象转 ...
- 理解 atime,ctime,mtime (下)
话不多说,开始下篇. # 前言 通过 "理解 atime,ctime,mtime (上)" 我们已经知道了atime 是文件访问时间:ctime是文件权限改变时间:mtime是文件 ...