ASP.NET Core 启动过程

ASP.NET Core 启动过程

  1. .Net Core 3.1
  2. VS 2019

创建一个新的ASP.NET Core Web API应用程序
在项目目录中有两个关键类 Program.cs 和 Startup.cs

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>();
                });
    }

在Program.cs 的Main函数 调用 CreateHostBuilder 这个方法
CreateHostBuilder 返回一个 IHostBuilder
IHostBuilder 是我们应用程序启动的核心接口

public interface IHostBuilder
    {
        IDictionary<object, object> Properties { get; }
        
        IHost Build();
        
        IHostBuilder ConfigureAppConfiguration(Action<HostBuilderContext, IConfigurationBuilder> configureDelegate);
        
        IHostBuilder ConfigureContainer<TContainerBuilder>(Action<HostBuilderContext, TContainerBuilder> configureDelegate);
      
        IHostBuilder ConfigureHostConfiguration(Action<IConfigurationBuilder> configureDelegate);
      
        IHostBuilder ConfigureServices(Action<HostBuilderContext, IServiceCollection> configureDelegate);
        
        IHostBuilder UseServiceProviderFactory<TContainerBuilder>(IServiceProviderFactory<TContainerBuilder> factory);
       
        IHostBuilder UseServiceProviderFactory<TContainerBuilder>(Func<HostBuilderContext, IServiceProviderFactory<TContainerBuilder>> factory);
    }

这个接口主要有以上6个方法
我们需要关注的是:

  1. ConfigureAppConfiguration
  2. ConfigureHostConfiguration
  3. ConfigureServices
    这三个方法
    通过修改Program 和 Startup 来演示启动过程
 public static IHostBuilder CreateHostBuilder(string[] args) =>
           Host.CreateDefaultBuilder(args)
               .ConfigureAppConfiguration(builder => {
                   Console.WriteLine("ConfigureAppConfiguration");
               })
               .ConfigureServices(service => {
                   Console.WriteLine("ConfigureServices");
               })
               .ConfigureHostConfiguration(builder => {
                   Console.WriteLine("ConfigureHostConfiguration");
               })
               .ConfigureWebHostDefaults(webBuilder =>
               {
                   Console.WriteLine("ConfigureWebHostDefaults");
                   webBuilder.UseStartup<Startup>();
               });

修改Startup类

public class Startup
   {
       public Startup(IConfiguration configuration)
       {
           Console.WriteLine("Startup");
           // snip
       }

       public IConfiguration Configuration { get; }

       // This method gets called by the runtime. Use this method to add services to the container.
       public void ConfigureServices(IServiceCollection services)
       {
           Console.WriteLine("Startup.ConfigureServices");
           // snip
       }

       // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
       public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
       {
           Console.WriteLine("Startup.Configure");
            // snip
       }
   }

查看输出结果

ConfigureWebHostDefaults
ConfigureHostConfiguration
ConfigureAppConfiguration
ConfigureServices
Startup
Startup.ConfigureServices
Startup.Configure

接下来调整一下CreateHostBuilder 中注册顺序

public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    Console.WriteLine("ConfigureWebHostDefaults");
                    webBuilder.UseStartup<Startup>();
                })
                .ConfigureServices(service => {
                    Console.WriteLine("ConfigureServices");
                })
                .ConfigureAppConfiguration(builder => {
                    Console.WriteLine("ConfigureAppConfiguration");
                })
                .ConfigureHostConfiguration(builder => {
                    Console.WriteLine("ConfigureHostConfiguration");
                });

然后重新执行查看结果

ConfigureWebHostDefaults
ConfigureHostConfiguration
ConfigureAppConfiguration
Startup
Startup.ConfigureServices
ConfigureServices
Startup.Configure

发现两次执行的结构有所不同,这个和委托注册进去的顺序有关系,实际上是按照一定的顺序执行的;
整个启动过程分5个阶段:

  1. ConfigureWebHostDefaults: 这个阶段注册了我们应用程序必要的几个组件,比如配置的组件,容器的组件
  2. ConfigureHostConfiguration:是用来配置我们应用程序启动时必要的配置,比如应用程序启动时需要监听的端口,URL地址等,在这个过程可以嵌入一些自己配置的类容,注入到配置的框架中
  3. ConfigureAppConfiguration:用于嵌入自己的配置文件供应用程序读取,这些配置将会在后续的应用程序执行过程中间每个组件读取
  4. ConfigureServices, ConfigureLogging, Startup, Startup.ConfigureServices:都是用来往容器里面注入我们的应用组件
  5. Startup.Configure:用来注入中间件,处理 HttpContext 整个请求过程

在整个启动过程中,Startup 这个类不是必要的.只是这样让代码结构更加合理

public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    Console.WriteLine("ConfigureWebHostDefaults");

                    webBuilder.ConfigureServices(services =>
                    {
                        Console.WriteLine("webBuilder.ConfigureServices");
                        services.AddControllers();
                    });


                    webBuilder.Configure(app => {
                        Console.WriteLine("webBuilder.Configure");
                        
                        app.UseHttpsRedirection();

                        app.UseRouting();

                        app.UseAuthorization();

                        app.UseEndpoints(endpoints =>
                        {
                            endpoints.MapControllers();
                        });
                    });
                })
                .ConfigureServices(service => {
                    Console.WriteLine("ConfigureServices");
                })
                .ConfigureAppConfiguration(builder => {
                    Console.WriteLine("ConfigureAppConfiguration");
                })
                .ConfigureHostConfiguration(builder => {
                    Console.WriteLine("ConfigureHostConfiguration");
                });

运行得到的结果

ConfigureWebHostDefaults
ConfigureHostConfiguration
ConfigureAppConfiguration
webBuilder.ConfigureServices
ConfigureServices
webBuilder.Configure

与之前执行的顺序也是一致的.

服务注册一般放在 Startup 的 ConfigureServices,一般是services.AddXXX
中间件的注册一般放在 Startup 的 Configure 一般是 app.UseXXX

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章