.NET Core原理(不知道怎么命名合适)
作者:cmliu;.NET Core启动都做了什么
.NET Core默认启动时的流程,您可以将图片另存为,在本地放大查看

.NET Core默认模板都做了些什么,首先贴出模板里面的Program.cs
public class Program
{
public static void Main(string[] args)
{
CreateWebHostBuilder(args).Build().Run();
} public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>();
}
解读:
1,入口main方法首先调用CreateWebHostBuilder(string[] args)方法获取一个[Web主机构建者WebHostBuilder]
2,CreateWebHostBuilder(string[] args)方法首先是调用:WebHost.CreateDefaultBuilder(args)创建一个默认的WebHostBuilder
在WebHost.CreateDefaultBuilder中,首先读取了命令行,ContentRoot配置;然后指定Kestrel的配置,日志提供程序,以及相关优先执行的中间件,并明确注入了IServer的实现类为KestrelServer;
并配置了IIS相关的服//WebHost.CreateDefaultBuilder部分源码
public static IWebHostBuilder CreateDefaultBuilder(string[] args)
{
var builder = new WebHostBuilder(); if (string.IsNullOrEmpty(builder.GetSetting(WebHostDefaults.ContentRootKey)))
{
builder.UseContentRoot(Directory.GetCurrentDirectory());
}
if (args != null)
{
builder.UseConfiguration(new ConfigurationBuilder().AddCommandLine(args).Build());
}
//该方法底层指定了Server的实现类为KestrelServer()
builder.UseKestrel((builderContext, options) =>
{
//省略其他代码
})
.ConfigureAppConfiguration((hostingContext, config) =>
{
//省略其他代码
})
.ConfigureLogging((hostingContext, logging) =>
{
//省略其他代码
})
.ConfigureServices((hostingContext, services) =>
{
//省略其他代码
})
.UseIIS()
.UseIISIntegration()
.UseDefaultServiceProvider((context, options) =>
{
//省略其他代码
}); return builder;
}
3, 调用WebHost.CreateDefaultBuilder(args)返回对象的UseStartup<Startup>()方法;用于将服务注册到容器(ConfigureServices方法),以及注册管道(Configure方法)
这里也说明一下Startup中的ConfigureServices,Configure两个方法与【下面】的Program类中ConfigureServices,Configure方法作用是一样的,都是用于将服务注册到容器(ConfigureServices方法),以及注册管道(Configure方法)
public static IWebHostBuilder CreateWebHostBuilder(string[] args)
{
var webHostBuilder = WebHost.CreateDefaultBuilder(args).ConfigureServices((services) =>
{
//省略其他代码,用于注册服务到容器
}).Configure((app) =>
{
//省略其他代码,用于注册管道
});
return webHostBuilder;
}
4,Statrtup中的代码,省略,后面进行解读
5,main方法中调用CreateWebHostBuilder(string[] args)返回的WebHostBuilder的Build方法
在这个Build方法中,直接初始化并返回了一个WebHost,并指定了WebHost的IServiceCollection(服务),IServiceProvider(容器),该WebHost有一个Server对象,对象实际上为KestrelServer
6,调用Build返回的WebHost对象的Run方法,用于启动服务器
*******实际上WebHost.Run方法中,首先获取一个ApplicationBuilder(就是Startip中的Configure方法中那个用于注入管道的类),并使用ApplicationBuilder.Build方法倒序构建RequestDelegate委托链管道
*******ApplicationBuilder.Build方法中,会把404中间件最为最后一个中间件注入到管道
*******使用获得的RequestDelegate,日志,HttpContextFactory相关参数,构造一个HostingApplication
*******最底层:以异步的方式启动WebHost.Server.StartAsync,即调用KestrelServer的StartAsync的方法,并在方法中指定了HostingApplication【此时KestrelServer已经有了一个拥有RequestDelegate管道的HostingApplication】
internal class WebHost : IWebHost
{
//省略其他代码
private readonly IServiceCollection _applicationServiceCollection;
private readonly IServiceProvider _hostingServiceProvider;
private IServiceProvider _applicationServices;
private IServer Server { get; set; }
//省略其他代码
public WebHost(IServiceCollection appServices,IServiceProvider hostingServiceProvider,
WebHostOptions options,IConfiguration config,AggregateException hostingStartupErrors)
{
//省略其他代码
_applicationServiceCollection = appServices;
_hostingServiceProvider = hostingServiceProvider;
//省略其他代码
}
//省略其他代码
public IServiceProvider Services
{
get
{
return _applicationServices;
}
}
//省略其他代码
public void Start()
{
StartAsync().GetAwaiter().GetResult();
}
//省略其他代码
public virtual async Task StartAsync(CancellationToken cancellationToken = default)
{
//省略其他代码
//构建RequestDelegate委托链管道
var application = BuildApplication(); _applicationLifetime = _applicationServices.GetRequiredService<IApplicationLifetime>() as ApplicationLifetime;
_hostedServiceExecutor = _applicationServices.GetRequiredService<HostedServiceExecutor>();
var diagnosticSource = _applicationServices.GetRequiredService<DiagnosticListener>();
var httpContextFactory = _applicationServices.GetRequiredService<IHttpContextFactory>();
//RequestDelegate委托链管道用于构建HostingApplication
var hostingApp = new HostingApplication(application, _logger, diagnosticSource, httpContextFactory);
//启动KestrelServer服务器,并将HostingApplication绑定到KestrelServer
await Server.StartAsync(hostingApp, cancellationToken).ConfigureAwait(false);
//省略其他代码
}
//省略其他代码 private RequestDelegate BuildApplication()
{
try
{
//省略其他代码
var builderFactory = _applicationServices.GetRequiredService<IApplicationBuilderFactory>();
var builder = builderFactory.CreateBuilder(Server.Features);
builder.ApplicationServices = _applicationServices;
//省略其他代码
return builder.Build();
}
catch (Exception ex)
{
//省略其他代码
}
}
//省略其他代码
}
7,KestrelServer启动HttpListener后,开始监听来自客户端浏览器的请求
8,KestrelServer接收到浏览器请求后,将请求参数构造出HttpContext,并选择对应的HTTP协议处理类,通过协议处理类的ProcessRequests方法(传说中的PR方法)
public abstract partial class HttpProtocol : IHttpResponseControl
{
//HTTP协议类调用HttpApplication
private async Task ProcessRequests<TContext>(IHttpApplication<TContext> application)
{
while (_keepAlive)
{
//省略其他代码
try
{
//省略其他代码
await application.ProcessRequestAsync(httpContext);
//省略其他代码
}
catch (BadHttpRequestException ex)
{
//省略其他代码
}
//省略其他代码
}
}
}
9,PR方法会去调用KestrelServer的HostingApplication的ProcessRequestAsync,而ProcessRequestAsync则是把HttpContext交给RequestDelegate管道处理
public class HostingApplication : IHttpApplication<HostingApplication.Context>
{
//委托链管道
private readonly RequestDelegate _application;
//省略其他代码
public HostingApplication(
RequestDelegate application,
ILogger logger,
DiagnosticListener diagnosticSource,
IHttpContextFactory httpContextFactory)
{
_application = application;
//省略其他代码
} //PR方法,调用委托链处理请求
public Task ProcessRequestAsync(Context context)
{
return _application(context.HttpContext);
}
//省略其他代码
}
.NET Core原理(不知道怎么命名合适)的更多相关文章
- 什么鬼,又不知道怎么命名class了
什么鬼,又不知道怎么命名class了 2015/10/25 · CSS · class 分享到:5 原文出处: 结一(@结一w3cplus) 相信写css的人都会遇到下面的问题: 糟糕,怎么命名 ...
- [转]什么鬼,又不知道怎么命名class了
(本文作者Mrcxt,原文链接:http://blog.csdn.net/mrcxt/article/details/52038884) 相信写css的人都会遇到下面的问题: 糟糕,怎么命名这个cla ...
- ASP.NET Core原理概述
ASP.NET Core 是一个控制台应用程序,在其 main 方法中创建一个Web服务器,以下是program.cs中的代码: using Microsoft.AspNetCore; using M ...
- EF Core 原理从源码出发(二)
紧接着我的上一篇博客,上回分析到ef 一个重要的对象,changetracker这个对象,当我们向DbContext添加对象的时候我们会调用如下代码. 1 private EntityEntry< ...
- day 变量的赋值原理 变量的命名规则
print(3*4*5*6/2) #简单的计算输出 x=3 y=4 print("x乘以y=",x*y) #运行5分钟 = 12 print(x*y) #在运行5分钟 = 12 ' ...
- EntityFramework Core 运行dotnet ef命令迁移背后本质是什么?(EF Core迁移原理)
前言 终于踏出第一步探索EF Core原理和本质,过程虽然比较漫长且枯燥乏味还得反复论证,其中滋味自知,EF Core的强大想必不用我再过多废话,有时候我们是否思考过背后到底做了些什么,到底怎么实现的 ...
- Cookies 初识 Dotnetspider EF 6.x、EF Core实现dynamic动态查询和EF Core注入多个上下文实例池你知道有什么问题? EntityFramework Core 运行dotnet ef命令迁移背后本质是什么?(EF Core迁移原理)
Cookies 1.创建HttpCookies Cookie=new HttpCookies("CookieName");2.添加内容Cookie.Values.Add(&qu ...
- [转]在.NET Core 2.x中将多个强类型设置实例与命名选项一起使用
自1.0版之前,ASP.NET Core已使用“ 选项”模式配置强类型设置对象.从那时起,该功能获得了更多功能.例如,引入了ASP.NET Core 1.1 IOptionsSnapshot,它允许您 ...
- 关于Segmentation fault (core dumped)几个简单问题的整理
有的程序可以通过编译,但在运行时会出现Segment fault(段错误).这通常都是指针错误引起的.但这不像编译错误一样会提示到文件一行,而是没有任何信息.一种办法是用gdb的step, 一步一步寻 ...
随机推荐
- 利用Unity3D制作简易2D计算器
利用Unity3D制作简易2D计算器 标签(空格分隔): uiniy3D 1. 操作流程 在unity3DD中创建一个新项目 注意选择是2D的(因为默认3D) 在Assets框右键新建C#脚本 在新建 ...
- Android 开发学习进程0.14 Bindview recyclerview popwindow使用 window类属性使用
BindView ButterKnife 优势 绑定组件方便,使用简单 处理点击事件方便,如adapter中的viewholder 同时父组件绑定后子组件无需绑定 注意 在setcontentview ...
- Flask实现RESTful API(注意参数位置解析)
准备工作 首先安装flask_restful三方组件 pip install flask_restful 在models.py中新建一个类,生成表,往里面插入一些数据.(flask要想使用ORM的话需 ...
- Node学习基础之安装node以及配置环境变量
第一步去node官网下载nodejs 我放在D盘 接着在cmd输入node -v 就能得到node的版本号 还有npm -v 下来进入安装好的目录 nodejs目录 创建两个文件夹 node_cach ...
- vue cli3.0使用svg全过程
VUE-cli3使用 svg-sprite-loader svg-sprite-loader 的插件,用来根据导入的 svg 文件自动生成 symbol 标签并插入 html 1.安装依赖 npm i ...
- 浏览器自动化的一些体会7 selenium webdriver的一些问题
1. 下载图片 这个链接说得最好,差不多所有可能的方法都列举了,除了没有提到用URLDownloadToFile,不过这和用WebClient差不多. https://stackoverflow.co ...
- Git操作之码云代码clone
安装Git https://git-scm.com/book/zh/v2/起步-安装-Git Git的网站上有详细的分各种系统的安装教程. 配置Git 1. 打开你要放置项目的本地路径,右键选择$ G ...
- 企业微信人员日程推送接口(python版)
企业在使用企业微信中,有时想批量推送员工日程信息.这里写了个接口工具分享给大家,供交流学习. 主入口程序: # -*- coding: utf-8 -*-import time as time imp ...
- idea工程在maven projects中显示灰色的解决办法
原文链接:https://blog.csdn.net/qq_30507287/article/details/83515461 在Mac上使用idea进行开发的过程中,一般在MavenProject中 ...
- (趣味哈哈镜)JMF中摄像头相关的问题
JMF已经非常古老了.最近由于做实验的需要,不得不使用JMF处理视频.开发使用win10系统和eclipse.使用中的问题如下: 1.首先想要使用JMF需要必须安装32位JDK,同时编译软件也需要是3 ...