.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, 一步一步寻 ...
随机推荐
- C#LeetCode刷题之#590-N叉树的后序遍历(N-ary Tree Postorder Traversal)
问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/4092 访问. 给定一个 N 叉树,返回其节点值的后序遍历. 例如 ...
- python处理转载博客html
前景 在转载别人博客的时候通常我们会通过复制html然后放到编辑器里面, 但是通常html里有很多杂七杂八的东西, 比如script, svg这些标签导致排版出现问题 例如由lu标签引起的 由svg标 ...
- 钉钉H5微应用
公司新项目要用到Vue+钉钉H5,在此记录一下免密登录: 引入插件: import * as dd from 'dingtalk-jsapi' import { login as loginUrl } ...
- 面经手册 · 第4篇《HashMap数据插入、查找、删除、遍历,源码分析》
作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 在上一章节我们讲解并用数据验证了,HashMap中的,散列表的实现.扰动函数.负载因 ...
- 【期外】 (一)关于LSH :局部敏感哈希算法
LSH是我同学的名字,平时我会亲切的称呼他为离骚,老师好,左移(leftshift),小骚骚之类的,最近他又多了一个新的外号:局部敏感哈希(Locally sensitive hashing). 好了 ...
- 《Java从入门到失业》第一章:计算机基础知识(二):计算机组成及基本原理
1.2计算机组成及基本原理 1.2.1硬件组成 这里说的计算机主要指微型计算机,俗称电脑.一般我们见到的有台式机.笔记本等,另外智能手机.平板也算.有了一台计算机,我们就能做很多事情了,比如我在写这篇 ...
- 从零开始讲解JavaScript中作用域链的概念及用途
从零开始讲解JavaScript中作用域链的概念及用途 引言 正文 一.执行环境 二.作用域链 三.块级作用域 四.其他情况 五.总结 结束语 引言 先点赞,再看博客,顺手可以点个关注. 微信公众号搜 ...
- IDEA编写Scala代码时自动显示变量类型
设置方法如下:settins -->Editor--> Code Style --> scala --Type Annotations 勾选框选部分 测试效果
- SSM框架环境搭建
SSM基础环境搭建 创建maven工程 next,finish,等待创建完成,创建完成后,src/main下只有webapp文件夹,我们需要手动创建java和resources,鼠标右击main,ne ...
- Robot Framework(3)——RIDE工具详解
上一篇介绍了用RF来简单运行案例,此篇主要了解一下工具操作 一.菜单栏 1.File 1>New Project:新建工程 2>Open Test Suite:打开测试套件 3>Op ...