美橙网站注册,wordpress自动修改图,南山网站建设乐云seo,制作图网店标前言一个Asp.NetCore项目#xff0c;知道大概的启动流程是有必要的#xff0c;比如后续遇见配置信息覆盖等相关问题时也大概知道是什么原因#xff0c;了解原因之后#xff0c;再去搜索引擎找答案#xff0c;否则目标不明确#xff0c;茫茫人海怎么会一下找到自己想要的知道大概的启动流程是有必要的比如后续遇见配置信息覆盖等相关问题时也大概知道是什么原因了解原因之后再去搜索引擎找答案否则目标不明确茫茫人海怎么会一下找到自己想要的除非是“偶遇”“偶遇”太难一起浅析一个Asp.NetCore 项目的启动流程正文先创建一个WebAPI项目用的是.NetCore3.1后续的项目例子都统一用.NetCore3.1,除非特殊说明项目如下如上图所示一个WebAPI项目启动方式本质也是一个控制台程序程序入口都是从Main函数开始就从里面方法看看大概都做了什么其中择取几个方法源码简要说明主要功能通过增加代码注释的方式(我觉得这样比较方便对应浏览)完整源代码从以下两个地址获取通过Everything查找工具比较方便查询代码主项目地址https://github.com/dotnet/aspnetcore/tree/v3.1.0 扩展项目地址https://github.com/dotnet/extensions/releases/tag/v3.1.6GitHub代码地址1. Host.CreateDefaultBuilder方法public static IHostBuilder CreateDefaultBuilder(string[] args)
{//实例化一个HostBuildervar builder new HostBuilder();//设置根目录builder.UseContentRoot(Directory.GetCurrentDirectory());//设置 Host相关配置的配置源builder.ConfigureHostConfiguration(config {//从环境变量中获取前缀名为DOTNET_config.AddEnvironmentVariables(prefix: DOTNET_);//如果命令行中有参数可从命令行中读取if (args ! null){config.AddCommandLine(args);}});//设置应用程序配置的配置源builder.ConfigureAppConfiguration((hostingContext, config) {var env hostingContext.HostingEnvironment;//根据运行环境加载不同的配置文件并开启了热更新config.AddJsonFile(appsettings.json, optional: true, reloadOnChange: true).AddJsonFile($appsettings.{env.EnvironmentName}.json, optional: true, reloadOnChange: true);if (env.IsDevelopment() !string.IsNullOrEmpty(env.ApplicationName)){var appAssembly Assembly.Load(new AssemblyName(env.ApplicationName));if (appAssembly ! null){config.AddUserSecrets(appAssembly, optional: true);}}//可从环境变量中获取config.AddEnvironmentVariables();//如果命令行中有参数可从命令行中读取if (args ! null){config.AddCommandLine(args);}})//配置日志显示.ConfigureLogging((hostingContext, logging) {//判断操作系统var isWindows RuntimeInformation.IsOSPlatform(OSPlatform.Windows);//如果是Windows系统配置对应的显示级别//IMPORTANT: This needs to be added *before* configuration is loaded, this lets//the defaults be overridden by the configuration.if (isWindows){// Default the EventLogLoggerProvider to warning or abovelogging.AddFilterEventLogLoggerProvider(level level LogLevel.Warning);}//获取配置文件中Logging 段相关的配置信息添加到日志配置中logging.AddConfiguration(hostingContext.Configuration.GetSection(Logging));//在控制台输出所以启动程序的时候就看见输出日志logging.AddConsole();//在Debug窗口输出logging.AddDebug();logging.AddEventSourceLogger();//如果是Windows系统可以在系统日志中输出日志if (isWindows){// Add the EventLogLoggerProvider on windows machineslogging.AddEventLog();}})//使用默认的依赖注入容器.UseDefaultServiceProvider((context, options) {var isDevelopment context.HostingEnvironment.IsDevelopment();options.ValidateScopes isDevelopment;options.ValidateOnBuild isDevelopment;});return builder;
}
2. ConfigureWebHostDefaults 方法public static IHostBuilder ConfigureWebHostDefaults(this IHostBuilder builder, ActionIWebHostBuilder configure)
{return builder.ConfigureWebHost(webHostBuilder {//指定是用的服务器及集成一些默认管道WebHost.ConfigureWebDefaults(webHostBuilder);//调用传入的委托这里是外部指定Startup类做服务注册和管道配置configure(webHostBuilder);});
}
2.1 WebHost.ConfigureWebDefaults方法internal static void ConfigureWebDefaults(IWebHostBuilder builder)
{builder.ConfigureAppConfiguration((ctx, cb) {if (ctx.HostingEnvironment.IsDevelopment()){//静态文件环境的配置启用StaticWebAssetsLoader.UseStaticWebAssets(ctx.HostingEnvironment, ctx.Configuration);}});//指定Kestrel作为默认的Web服务器builder.UseKestrel((builderContext, options) {options.Configure(builderContext.Configuration.GetSection(Kestrel));})// 服务中间的注册包含路的中间件注册.ConfigureServices((hostingContext, services) {// 针对配置节点AllowedHosts改变时的回调// Fallbackservices.PostConfigureHostFilteringOptions(options {if (options.AllowedHosts null || options.AllowedHosts.Count 0){// AllowedHosts: localhost;127.0.0.1;[::1]var hosts hostingContext.Configuration[AllowedHosts]?.Split(new[] { ; }, StringSplitOptions.RemoveEmptyEntries);// Fall back to * to disable.options.AllowedHosts (hosts?.Length 0 ? hosts : new[] { * });}});//对应配置改变时触发通知// Change notificationservices.AddSingletonIOptionsChangeTokenSourceHostFilteringOptions(new ConfigurationChangeTokenSourceHostFilteringOptions(hostingContext.Configuration));services.AddTransientIStartupFilter, HostFilteringStartupFilter();if (string.Equals(true, hostingContext.Configuration[ForwardedHeaders_Enabled], StringComparison.OrdinalIgnoreCase)){services.ConfigureForwardedHeadersOptions(options {options.ForwardedHeaders ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;// Only loopback proxies are allowed by default. Clear that restriction because forwarders are// being enabled by explicit configuration.options.KnownNetworks.Clear();options.KnownProxies.Clear();});services.AddTransientIStartupFilter, ForwardedHeadersStartupFilter();}services.AddRouting();})//对使用IIS相关中间件.UseIIS().UseIISIntegration();
}
3. Build方法其实这个方法就是根据之前配置构造出一个IHost对象public IHost Build()
{if (_hostBuilt){throw new InvalidOperationException(Build can only be called once.);}_hostBuilt true;//执行ConfigureHostConfiguration添加的一系列配置回调方法BuildHostConfiguration();//运行环境相关创建如ApplicationName、EnvironmentName、ContentRootPath等CreateHostingEnvironment();//构建HostBuilderCreateHostBuilderContext();//执行ConfigureAppConfigureation添加的一系列配置回调方法BuildAppConfiguration();//注入默认服务如IHost、ILogging等执行ConfigureServices添加的一系列回调方法CreateServiceProvider();return _appServices.GetRequiredServiceIHost();
}
4. Run()方法开启服务器之后就可以进行请求了综上几个关键方法从其中Host这个关键词出现很多次其实在Asp.Net Core应用中是通过配置并启动一个Host来完成应用程序的启动和生命周期的管理。而Host主要就是对Web Server的配置和请求处理管理的管理简要流程如下图在整个启动流程中返回的IHostBuilder中暴露配置和注入的相关接口可用于自己定义扩展接下来通过打印的方式来看看一下几个暴露方法的执行顺序其实以上Build方法的时候已经明确了对应方法的顺序改造代码如下Startup方法中的三个方法也增加对应的打印运行如下如上图除了Startup中的ConfigureServices会跟随ConfigureWebHostDefaults改变以外其他方法顺序都是固定。那这些方法主要作用都是什么呢如下图图中Program.ConfigureServices和Startup.ConfigureServices的执行顺序会根据ConfigureWebHostDefaults的位置改变会交替变动总结以上内容只是提取了其中比较关键的流程进行说明并没有详细解析源代码这里只是先浅析后续再继续一起深究源代码下一节说说依赖注入