asp.net core 3.1 入口:Program.cs中的Main函数
本文分析program.cs 中main()函数中代码的运行顺序分析asp.net core程序的启动,重点不是剖析源码,而是理清程序开始时执行的顺序。到底用了哪些实例,哪些法方。
asp.net core 3.1 的程序入口在项目program.cs文件里,如下。
ususing system; using system.collections.generic; using system.linq; using system.threading.tasks; using microsoft.aspnetcore.hosting; using microsoft.extensions.configuration; using microsoft.extensions.hosting; using microsoft.extensions.logging; namespace webdemo { public class program { public static void main(string[] args) { createhostbuilder(args).build().run(); } public static ihostbuilder createhostbuilder(string[] args) => host.createdefaultbuilder(args) .configurewebhostdefaults(webbuilder => { webbuilder.usestartup<startup>(); }); } }
1. program类
program类是定义在项目根目录program.cs文件中,所有.net core程序的入口,包括asp.net core 程序。这很有意思,就有点类似控制端程序。相比之前的web项目没有任何程序入口只有web.config、global这类配置文件和全局文件这种没有程序入口web项目,我觉得这类更容易理解asp.net core是怎么工作的。
在asp.net core 3.1中 的program类里,定义了2个方法:main() 和createhostbuilder()
2. 主程序入口program.main()方法
public static void main(string[] args) { createhostbuilder(args).build().run(); }
main() 方法是整个项目的入口方法,就如同c系列语言,所有的程序入口都是。这里main()只有一行代码,但是实际上执行了三个函数c:
1 ihostbuilder builder= createhostbuilder(args); 2 ihost host=builder.build(); 3 host.run();
第一行,是定义在program类的createhostbuilder 它主要产生一个ihostbuilder实例builder。
第二行,通过builder.build()法方产生一个ihost实例 host。
第三含,通过host.run()方法,开始运行web项目,这时候就可以响应各种请求了。
而这个过程里最繁琐的就是创建builder,本文重点篇幅就是在这里。
3. 创建并配置主机builder:program.createhostbuilder(args)法方
分解createhostbuilder(args) 的定义
此法方通过lamada表达式定义在pogram类中。因为它就执行了一句化,所以可以用这种简便的方式定义(关于匿名函数、lamada、内置委托可以参考我之前的文章c# 匿名方法(函数) 匿名委托 内置泛型委托 lamada1)。为了方便阅读按照上面刨析main()法方,所以它实际的定义如下:
1 public static ihostbuilder createhostbuilder(string[] args) 2 { 3 ihostbuilder builder = host.createdefaultbuilder(args); 4 action < iwebhostbuilder > configaction = delegate(iwebhostbuilder webbuilder) 5 { 6 webbuilder.usestartup<startup>(); 7 }; 8 builder=builder.configurewebhostdefaults(configaction); 9 return builder; 10 }
3.1. builder诞生 :生成ihostbuilder
将从host.createhostbuilder()法方分析入手
createhostbuilder()法方的第一行代码是调用host.createdefaultbuilder(args)法方,来创建ibuilder 对象实例。
ihostbuilder builder = host.createdefaultbuilder(args);
ihostbuilder是一个非常重要的实例,有了这个实例才可以继续后续的加载更多的配置操作。通过ihostbuilder.build()生产ihost实例。最终通过ihost.run()运行项目。
3.1.1 host类——用于产生初始的builder静态类
host类是定义在microsoft.extensions.hosting命名空间(program.cs中引用了该命名公开)下的静态类.在program.cs里引入。
声明如下:
1 using microsoft.extensions.hosting; 2 3 namespace microsoft.extensions.hosting 4 { 5 public static class host 6 { 7 public static ihostbuilder createdefaultbuilder(); 8 public static ihostbuilder createdefaultbuilder(string[] args); 9 } 10 }
host静态类就一个法方就是createdefaultbuilder() 。合计2个重载声明:一个带参数,一个不带参数。参考源码(.net core 3.0之深入源码理解host(一)2)不带参数的重载实际在是将null作为参数调用带参数形式,如下:
1 public static ihostbuilder createdefaultbuilder() =>createdefaultbuilder(args: null);
3.1.2 host.createdefaultbuilder(args)方法
官方说明是用预先配置的默认值初始化一个microsoft.extensions.hosting.hostbuilder实例(initializes a new instance of the microsoft.extensions.hosting.hostbuilder class with pre-configured defaults,详细见参考官方文档3)。
相关操作有:设置根目录contentrootpath ;给host.iconfiguration 加载:环境变量environmentname,命令行参数args,配置文件iconfiguration.[environmentname] json;还有加载日志模块等等。
详细见参考文档2、3,其中.net core 3.0之深入源码理解host(一),作者从源码角度剖析了此法方,官方文档host.createdefaultbuilder 方法官方说明了法方操作那些内容。
3.2. ihostbuilder转变成iwebhostbuilder
继续对host.createhostbuilder()法方分析,在3.1建立了ihostbuilder实例后,将通过builder.configurewebhostdefaults(action <iwebhostbuilder >)方法将ihostbuilder实例转变为一个web主机性质的webbuilder(iwebhostbuilder)
ihoustbuilder.configurewebhostdefaults(action <iwebhostbuilder>)方法定义在microsoft.extensions.hosting.generichostbuilderextensions静态类中(generichostbuilderextensions.cs),此静态类就定义这一个静态方法。
3.2.1. configurewebhostdefaults()参数
此处参数configure是一个内置委托action <iwebhostbuilder>,这个委托的定义就执行一行代码:
webbuilder.usestartup<startup>();
3.2.2. configurewebhostdefaults()方法定义
其实configurewebhostdefaults(action <iwebhostbuilder >)方法是一个ihostbuilder的扩展方法(所以之前的写法并不准确,缺少了this builder参数,之前省略了)。
为了方便阅读法,用3.中的方式码剖析如下:
1 public static ihostbuilder configurewebhostdefaults(this ihostbuilder builder, action<iwebhostbuilder> configure) 2 { 3 action<iwebhostbuilder> webconfigure = delegate(iwebhostbuilder webhostbuilder) 4 { 5 webhost.configurewebdefaults(webhostbuilder); 6 configure(webhostbuilder); 7 }; 8 return builder.configurewebhost(webconfigure); 9 }
上一篇: 除夕喝什么饮料,健康又美味,快收藏起来!
下一篇: 基于 Redis 实现 CAS 操作