欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

asp.net core 3.1 入口:Program.cs中的Main函数

程序员文章站 2023-10-27 17:54:22
本文分析Program.cs 中Main()函数中代码的运行顺序分析asp.net core程序的启动,重点不是剖析源码,而是理清程序开始时执行的顺序。到底用了哪些实例,哪些法方。asp.net core 3.1 的程序入口在项目Program.cs文件里,如下。ususing System; us ......

本文分析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         }