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

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