.NET Core開發實戰(第4課:Startup:掌握ASP.NET Core的啟動過程)--學習筆記


04 | Startup:掌握ASP.NET Core的啟動過程

新建一個 ASP.NET Core Web 應用程序

選擇 API

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 方法返回了一個 IHostBuilder

它是應用程序啟動的核心接口

IHostBuilder 接口有六個方法:

主要關注以下三個:

  • ConfigureAppConfiguration
  • ConfigureHostConfiguration
  • ConfigureServices

接下來,我們添加一些代碼演示整個應用程序的啟動過程:

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 Startup(IConfiguration configuration)
{
    Console.WriteLine("Startup");
    ...
    
public void ConfigureServices(IServiceCollection services)
{
    Console.WriteLine("ConfigureServices");
    ...
    
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    Console.WriteLine("Configure");
    ...

啟動程序查看輸出:

ConfigureWebHostDefaults
ConfigureHostConfiguration
ConfigureAppConfiguration
ConfigureServices
Startup
Startup.ConfigureServices
Startup.Configure

調整一下委托的注冊順序

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

本質上,如果查看源碼會發現,委托注冊進去之后,實際上是按照一定的順序來執行的:

1、ConfigureWebHostDefaults

這個階段注冊了應用程序必要的幾個組件,比如配置的組件、容器組件

2、ConfigureHostConfiguration

用於配置應用程序啟動時必要的配置,比如應用程序啟動時所需要監聽的端口,URL 地址

在這個過程可以嵌入一些自己配置的內容,注入到配置的框架中

3、ConfigureAppConfiguration

用於嵌入自己的配置文件,供應用程序讀取,這些配置將會在后續的應用程序執行過程中間每個組件讀取

4、ConfigureServices, ConfigureLogging, Startup, Startup.ConfigureServices

用於往容器里注入應用的組件

5、Startup.Configure

用於注入中間件,處理 HttpContext 整個請求過程

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    Console.WriteLine("Startup.Configure");
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.UseHttpsRedirection();

    app.UseRouting();

    app.UseAuthorization();

    app.UseFileServer();

    app.UseWebSockets();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });
}

在整個啟動的過程中,Startup 這個類不是必要的,只是讓代碼結構更加合理

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

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

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

                app.UseHttpsRedirection();

                app.UseRouting();

                app.UseAuthorization();

                app.UseFileServer();

                app.UseWebSockets();

                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

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();
    services.AddAuthentication();
    services.AddAuthorization();
    Console.WriteLine("Startup.ConfigureServices");
    services.AddControllers();
}

中間件的注冊一般放在 Startup 的 Configure

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    Console.WriteLine("Startup.Configure");
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.UseHttpsRedirection();

    app.UseRouting();

    app.UseAuthorization();

    app.UseFileServer();

    app.UseWebSockets();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });
}

GitHub源碼鏈接:

https://github.com/MINGSON666/Personal-Learning-Library/tree/main/DotNetCoreDevelopmentActualCombat/StartupDemo

知識共享許可協議

本作品采用知識共享署名-非商業性使用-相同方式共享 4.0 國際許可協議進行許可。

歡迎轉載、使用、重新發布,但務必保留文章署名 鄭子銘 (包含鏈接: http://www.cnblogs.com/MingsonZheng/ ),不得用於商業目的,基於本文修改后的作品務必以相同的許可發布。

如有任何疑問,請與我聯系 (MingsonZheng@outlook.com) 。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM