源码解读asp.net core源码启动流程精细解读

Posted 四处观察

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了源码解读asp.net core源码启动流程精细解读相关的知识,希望对你有一定的参考价值。

引言

    core出来至今,已经7年了,我接触也已经4年了,从开始的2.1,2.2,3.1,5,6再到如今的7,一直都有再用,虽然我是一个Winform仔,但是源码一直从3.1到7都有再看,然后在QQ上面也一直比较活跃,之前好几年前一直说给大家解读asp.net core源码,在之前的博客中,讲的都是比较粗略化的,因为东西太多了,写也写不少东西,所以总是不了了之,然后在上个月底的时候,在微信和群友聊天,说到了这块,就想着,直播讲解一下,然后就定在了五月份去讲解源码,然后在前天,也就是五月十八号,在微信直播,哔哩哔哩录制,讲解了一下asp.net core源码,不过,由于很少直播,导致整个直播效果不是很好,因为整个节奏都是按照我自己对源码的熟悉程度来解读的,以及源码太多,我想一次性讲解完,所以导致后面的观众很少,在这向诸位观众道个歉,然后昨天,我就开始对前天晚上的直播做了总结,以及把我本来计划没有说的话,写在了一个文档里,其中包括对于直播的总结,以及开发者如何提升自己的认知还有逻辑思维能力,以及自己的一些建议,同时在昨天也开始整理asp.net core源码的解读文档,从昨天写到现在,终于写完了,希望接下来分享的东西对大家能够有帮助。

目录

    整体目录分为以下目录,从最开始的WebApplication,WebApplicationBuilder,在到WebApplicationBuilder内部的构造函数做了那些事情,每一步尽量做到了精细化,每一行代码能讲清楚就讲清楚,同时针对默认创建的Api项目的重要的几个源码做了精细化讲解,包括AddControllers,内部的AddMvcCore,注入的那么多的服务,在到如何创建GenericWebHostBuilder,构建GenericWebHostService,注入Kestrel,IIS等,配置服务,配置Host还有Configuration。

    再到WebApplication的Build方法,又如何把所有的中间件串联起来,做了哪些事情,返回的IHost是什么,在哪里,也写了MapControllers如何给EndpointDataSource添加Endpoint,如何订阅更新Endpoint的变化。又如何创建我们的请求的RequestDelegate,以及ResourceInvoker,如何执行过滤器,创建控制器,调用接口,如何请求,如何响应,以及最根本的监听,都写在了本文档里,总之把我认为最细致化的东西都给大家呈现了出来,哈哈哈当然拉,在最后的写入响应那块,实际上有的不是很详细,因为,源码跳的地方有点多,我把中间WriteAsync我认为承上启下的部分写了出来,方便大家去找到最根本的地方,

    本文档,将一个默认的WebApi项目如何启动,如何监听,以及请求过来,如何响应并且写入数据,展现出来,有的地方可以支持自定义的接口类型,也说了出来,同时相信大家,在看了本文档,再结合源码,能够很清晰的知道,自己如果需要自定义一些东西,是可以明白源码在哪里看,实现哪些接口,生命周期又是什么,如果在结合微软文档,知道了一些可以自定义的某个功能IFeature,都是可以的。

    希望大家,都能够对asp.net core源码有一个更深层次的了解,一个框架我们不仅仅是会用,还得用的好,才能提升我们的竞争力。

结尾

    最后,恳求各位大家在转载本文档的时候,能够保留文档最后的个人信息,尊重一下本人的版权,谢谢大家,码字不易,望各位理解,后续,会给大家带来更多的源码解读。

    直播总结文档地址:里面包括个人的一些心得建议,以及提升认知的方法。

    链接:https://pan.baidu.com/s/12pzpi5uCaL3p4afvWAtc-Q
    提取码:bv83

    asp.net core源码解读文档,就是如图上的文档,

    链接:https://pan.baidu.com/s/1V5wUD2R0WMQ8hOHulhQnHA
    提取码:p2a8

    所阅读的asp.net core源码地址

    链接:https://pan.baidu.com/s/15a16TNowbpatkJqDF8qk1A
    提取码:k7oh

    所阅读的Libraries源码地址

    链接:https://pan.baidu.com/s/1cy_5C3cwn9TQXqFjKUvWgQ
    提取码:afeo

    直播回放:

    【asp.net core源码快速解读-哔哩哔哩】 https://b23.tv/G8p6j9D

    最后如果有什么问题可以随时联系我,QQ934550201,或者添加群聊都可以找到我。

    

  

 

ASP.NET Core 3.1--中间件源码解读--RequestDelegate--ApplicationBuilder.Use

一、RequestDelegate的定义
从RequestDelegate定义可以看出,RequestDelegate是接收请求上下文HttpContext的一个委托,RequestDelegate既然是一个委托,委托就是一个方法,所以RequestDelegate就是个方法,是个接受请求上下文的方法。

public delegate Task RequestDelegate(HttpContext context);

二、 IApplicationBuilder.Use的定义
我们对比来看,下面这个func是接收1个int 类型的参数,返回1个string类型的委托

Func<int, string> func = new Func<int, string>(i => 
{
    return "abc";
});
string result = func(123);

在看ApplicationBuilder.Use()的定义
ApplicationBuilder.Use方法接收1个Func委托,这个Func接收1个RequestDelegate类型的参数,返回1个RequestDelegate类型,上面说了RequestDelegate是个方法,那么也就是说ApplicationBuilder.Use方法接收1个方法,返回1个方法。

IApplicationBuilder Use(Func<RequestDelegate, RequestDelegate> middleware);

三、ApplicationBuilder.Use需要的参数的简写
这时候requestdelegate是个方法,但是是什么方法,我们还不知道,我们往下看

//1、Func委托,这个Func接收1个RequestDelegate类型的参数,返回1个RequestDelegate类型
Func<RequestDelegate, RequestDelegate> func = new Func<RequestDelegate, RequestDelegate>((RequestDelegate requestdelegate) =>
{
    return new RequestDelegate(async (context) =>
    {
        await context.Response.WriteAsync("接收1个带RequestDelegate类型的参数,返回RequestDelegate类型的委托");
    });
});

//2、简写这个委托
Func<RequestDelegate, RequestDelegate> func = (requestdelegate =>
{
    return new RequestDelegate(async (context) =>
    {
        await context.Response.WriteAsync("简写func委托!");
    });
});

//3、Use中间件,最终简写
app.Use(requestdelegate =>
{
    return new RequestDelegate(async (context) =>
    {
        await context.Response.WriteAsync("Use中间件!");
    });
});

四、看源码解读中间件注册和执行流程

1、为什么输出顺序是This is Middleware 3=>This is Middleware 2=>This is Middleware 1?
2、为什么输出顺序是This is Hello World 1 Start=>This is Hello World 2 Start=>This is Hello World 3 Start=>This is Hello World 3 End=>This is Hello World 2 End=>This is Hello World 1 End?
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory)
{ 
    app.Use(next =>
    {
        Console.WriteLine("This is Middleware 1");
        return new RequestDelegate(
            async context =>
            {
                await context.Response.WriteAsync("This is Hello World 1 Start");
                await next.Invoke(context);
                await context.Response.WriteAsync("This is Hello World 1 End");
            });
    });
    app.Use(next =>
    {
        Console.WriteLine("This is Middleware 2");
        return new RequestDelegate(
            async context =>
            {
                await context.Response.WriteAsync("This is Hello World 2 Start");
                await next.Invoke(context);
                await context.Response.WriteAsync("This is Hello World 2 End");
            });
    });
    app.Use(next =>
    {
        Console.WriteLine("This is Middleware 3");
        return new RequestDelegate(
            async context =>
            {
                await context.Response.WriteAsync("This is Hello World 3 Start");
                await context.Response.WriteAsync("This is Hello World 3 End");
            });
    });  
}

1、ApplicationBuilder.Use方法源码解读
从源码看出ApplicationBuilder.Use方法就是把Func<RequestDelegate, RequestDelegate> middleware添加到_components这个集合里,而从_components的定义看出_components是个委托集合。

 

2、中间件执行源码解读

Build()的时候执行注册的中间件
从源码看出有个默认的RequestDelegate app,把委托集合反转,遍历执行。
 
第3个中间件的next是默认的RequestDelegate app=>第2个中间件的next是第3个中间件的返回值=>第1个中间件的next是第2个中间件的返回值
 
所以先输出This is Middleware 3,后输出This is Middleware 2,最后输出This is Middleware 1,最终返回的是第1个中间件,最终Application就是Middleware 1。
 
所以最后的输出顺序是This is Hello World 1 Start--->This is Hello World 2 Start--->This is Hello World 3 Start--->This is Hello World 3 End--->This is Hello World 2 End--->This is Hello World 1 End

 总结中间件

1、中间件就像俄罗斯套娃一样,一环套一环
2、最后返回的是第1个中间件

以上是关于源码解读asp.net core源码启动流程精细解读的主要内容,如果未能解决你的问题,请参考以下文章

asp.net core启动源码以及监听,到处理请求响应的过程

以太坊源码交易流程源码解读

ASP.NET Core项目解读之launchSettings.json

ASP.NET Core项目解读之launchSettings.json

ElasticSearchEs 源码之 PeerRecoverySourceService 源码解读

ElasticSearchEs 源码之 HttpServerTransport 源码解读