【ASP.NET Core】运行原理之创建WebHost
本节将分析WebHost.CreateDefaultBuilder(args).UseStartup<Startup>().Build();代码。
源代码参考.NET Core 2.0.0
问题概要 WebHost.CreateDefaultBuilder(args)该方法为WebHost类的静态方法,内部创建1个WebHostBuilder。
在UseKestrel()方法中,注册了3个服务到List<Action<WebHostBuilderContext, IServiceCollection>>字段上。(以供后续注册)
public static IWebHostBuilder UseKestrel(this IWebHostBuilder hostBuilder) { return hostBuilder.ConfigureServices((Action<IServiceCollection>) (services => { services.AddSingleton<ITransportFactory, LibuvTransportFactory>(); services.AddTransient<IConfigureOptions<KestrelServerOptions>, KestrelServerOptionsSetup>(); services.AddSingleton<IServer, KestrelServer>(); })); } public IWebHostBuilder ConfigureServices(Action<WebHostBuilderContext, IServiceCollection> configureServices) { this._configureServicesDelegates.Add((_, services) => configureServices(services)); return (IWebHostBuilder) this; } UseContentRootUseContentRoot方法则是添加到IConfiguration字段上,这个字段在构造函数初始化
this._config = (IConfiguration) new ConfigurationBuilder().AddEnvironmentVariables("ASPNETCORE_").Build();
ConfigureAppConfiguration方法是添加到List<Action<WebHostBuilderContext, IConfigurationBuilder>>字段上
在外部添加了
AddJsonFile("appsettings.json")、AddJsonFile(string.Format("appsettings.{0}.json", (object) hostingEnvironment.EnvironmentName))
AddEnvironmentVariables()
AddCommandLine(args)
ConfigureLogging注册Log到ServiceCollection上
在外部添加了3个ILoggerProvider
logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
logging.AddConsole();
logging.AddDebug();
UseDefaultServiceProvider配置和替换服务
var options = new ServiceProviderOptions { ValidateScopes = context.HostingEnvironment.IsDevelopment()}; services.Replace(ServiceDescriptor.Singleton<IServiceProviderFactory<IServiceCollection>>((IServiceProviderFactory<IServiceCollection>) new DefaultServiceProviderFactory(options))); UseStartupUseStartup相当于注册了一个IStartup服务。
public static IWebHostBuilder UseStartup(this IWebHostBuilder hostBuilder, Type startupType) { string name = startupType.GetTypeInfo().Assembly.GetName().Name; return hostBuilder.UseSetting(WebHostDefaults.ApplicationKey, name).ConfigureServices((Action<IServiceCollection>) (services => { if (typeof (IStartup).GetTypeInfo().IsAssignableFrom(startupType.GetTypeInfo())) ServiceCollectionServiceExtensions.AddSingleton(services, typeof (IStartup), startupType); else ServiceCollectionServiceExtensions.AddSingleton(services, typeof (IStartup), (Func<IServiceProvider, object>) (sp => { IHostingEnvironment requiredService = sp.GetRequiredService<IHostingEnvironment>(); return (object) new ConventionBasedStartup(StartupLoader.LoadMethods(sp, startupType, requiredService.EnvironmentName)); })); })); }根据Startup是否继承IStartup,来决定注册的方式。未继承的时候,会使用ConventionBasedStartup来封装自定义的Startup。
BuildBuild方法是WebHostBuilder最终的目的,将构造一个WebHost返回。