始于WebHost
- 准备阶段: var builder = new WebHostBuilder(),然后给WebHostBuilder各种填参数
- 构建阶段: var host = builder.Builder() , 主要负责依懒注入的初始化,以及host的初始化
- 启动阶段: host.start();
- 运行阶段
program.cs
ASP.NET Core 程序基于一个命令行的程序运行,程序的入口在program.cs的main方法。
public static void Main(string[] args){ WebHost.CreateDefaultBuilder(args) .UseStartup<Startup>() .Build() .Run(); }
var host = new WebHostBuilder() .UseKestrel() .UseContentRoot(Directory.GetCurrentDirectory()) .UseIISIntegration() .UseStartup<Startup>() .Build();
CreateDefaultBuilder方法
这个方法负责返回给我们一个WebHostBuilder, 并且调用了以下扩展方法:
- UseKestrel 使用kestrel server来处理请求
- UseContentRoot 设置站点目录
- ConfigureAppConfiguration
- ConfigureLogging
UseKestrel
WebHost负责托管ASP.NET Core,但是它并不真正从服务器网卡上监听端口以及将网络字节转换到.net core的管道。这些由IServer来处理。
这里先简单了解一下这个过程,我们后面会在IServer的环节再详述。我们这里使用的UseKestrel 来自于github上的项目 KestrelHttpServer。
里面的Kestrel项目下有一个WebHostBuilderKestrelExtensions类。里面就是这个 UseKestrel扩展方法的定义:
public static IWebHostBuilder UseKestrel( this IWebHostBuilder hostBuilder){ return hostBuilder.ConfigureServices(services => { // Don't override an already-configured transport services.TryAddSingleton< ITransportFactory, SocketTransportFactory>(); services.AddTransient< IConfigureOptions<KestrelServerOptions>, KestrelServerOptionsSetup>(); services.AddSingleton< IServer, KestrelServer>(); }); }
其实也很简单,都是在进行Server依赖的配置,因为最终的执行都由WebHost来展控。所以WebHost大量依赖的其它外部组件都被定义成接口放到了HttpAbstractions里面,然后由外部扩展方法(多以Use开头,进行配置)
ASP.NET Core源码里面大量使用扩展方法进行Servier DI的配置,扩展方法定义在各种不同的命名空间以及项目下。如果不习惯或者不了解相关的部分会觉得有些痛苦。
ConfigureAppConfiguration
这个方法专门用来为 WebHostBuilder添加配置,包括appsettings.json的、命令行参数以及环境变量。关于配置这一节我们留在后面具体来讲。
config.AddJsonFile( "appsettings.json", optional: true, reloadOnChange: true) .AddJsonFile( $"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);config.AddEnvironmentVariables();config.AddCommandLine(args);
ConfigureLogging
logging也是 ASP.NET Core内置组件中的很重要一个,这个方法在默认已经为我们添加了appsettings中的logging配置以及控制台log。关于日志这一节我们留在后面具体来讲。
logging.AddConfiguration( hostingContext.Configuration.GetSection("Logging"));logging.AddConsole();logging.AddDebug();
UseStartup<>
Startup.cs这个类主要做两件事情的配置Service DI和http管道,这些都是在WebHost启动之前就需要确定下来的。而UseStartup就是将我们定义的Startup.cs和 IStartup绑定起来,让WebHost可以找得到。 怎么绑定呢? 当然还是依赖注入:
if (typeof(IStartup) .GetTypeInfo() .IsAssignableFrom(startupType.GetTypeInfo())) { services.AddSingleton(typeof(IStartup), startupType); }else{ services.AddSingleton(typeof(IStartup), sp => { var hostingEnvironment = sp.GetRequiredService<IHostingEnvironment>(); return new ConventionBasedStartup( StartupLoader.LoadMethods( sp, startupType, hostingEnvironment.EnvironmentName)); }); }
VS为我们添加的Startup.cs默认不继续IStartup接口,所以是采用Convention的这种方式,当然我们也可以继承IStartup则直接注册成单例到应用程序。
以上是整个 WebHostBuilder的准备阶段,即往里面放了很多的参数。下一篇我们将接着讲Builder阶段,给了你那么多,你要开始制造点什么东西给我了。
本文首发于公众号jessetalk,转载请保留公众号二维码。
原文: http://www.jessetalk.cn/2017/11/11/aspnet-core-object-webhost/