04 | Startup:掌握ASP.NET Core的启动过程
新建一个 ASP.NET Core Web 应用程序
选择 API
代码语言:javascript复制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
接下来,我们添加一些代码演示整个应用程序的启动过程:
代码语言:javascript复制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 的三个方法中添加一些代码
代码语言:javascript复制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");
...
启动程序查看输出:
代码语言:javascript复制ConfigureWebHostDefaults
ConfigureHostConfiguration
ConfigureAppConfiguration
ConfigureServices
Startup
Startup.ConfigureServices
Startup.Configure
调整一下委托的注册顺序
代码语言:javascript复制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");
})
;
会得到不同的结果
代码语言:javascript复制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 整个请求过程
代码语言:javascript复制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 这个类不是必要的,只是让代码结构更加合理
代码语言:javascript复制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");
})
;
}
启动程序查看输出:
代码语言:javascript复制ConfigureWebHostDefaults
ConfigureHostConfiguration
ConfigureAppConfiguration
webBuilder.ConfigureServices
ConfigureServices
webBuilder.Configure
服务注册一般放在 Startup 的 ConfigureServices,一般是services.AddXXX
代码语言:javascript复制public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddAuthentication();
services.AddAuthorization();
Console.WriteLine("Startup.ConfigureServices");
services.AddControllers();
}
中间件的注册一般放在 Startup 的 Configure
代码语言:javascript复制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();
});
}