.net core web 启动过程(3)-Hosting
关于Hosting展示代码来源 .net core的runtime-8.0.7源码:https://github.com/dotnet/runtime
/// <summary> /// A program initialization utility. /// </summary> public partial class HostBuilder : IHostBuilder { private const string HostBuildingDiagnosticListenerName = "Microsoft.Extensions.Hosting"; private const string HostBuildingEventName = "HostBuilding"; private const string HostBuiltEventName = "HostBuilt"; //这部分代码在本系列文章第一章已经描述,此处不过多介绍 private readonly List<Action<IConfigurationBuilder>> _configureHostConfigActions = new List<Action<IConfigurationBuilder>>(); private readonly List<Action<HostBuilderContext, IConfigurationBuilder>> _configureAppConfigActions = new List<Action<HostBuilderContext, IConfigurationBuilder>>(); private readonly List<Action<HostBuilderContext, IServiceCollection>> _configureServicesActions = new List<Action<HostBuilderContext, IServiceCollection>>(); private readonly List<IConfigureContainerAdapter> _configureContainerActions = new List<IConfigureContainerAdapter>(); private IServiceFactoryAdapter _serviceProviderFactory; //这些在属性会在Build()方法中不同阶段中被创建 private bool _hostBuilt; private IConfiguration? _hostConfiguration; private IConfiguration? _appConfiguration; private HostBuilderContext? _hostBuilderContext; private HostingEnvironment? _hostingEnvironment; private IServiceProvider? _appServices; private PhysicalFileProvider? _defaultProvider; /// <summary> /// Initializes a new instance of <see cref="HostBuilder"/>. /// </summary> public HostBuilder() { //构造函数中默认 初始化 ServiceProviderFactory,不过可以通过HostBuilder.UseServiceProviderFactory方法覆盖掉 _serviceProviderFactory = new ServiceFactoryAdapter<IServiceCollection>(new DefaultServiceProviderFactory()); } }
再来回顾一下HostBuilder的Build过程中都经历了哪些阶段。
public partial class HostBuilder : IHostBuilder { /// <summary> /// Run the given actions to initialize the host. This can only be called once. /// </summary> /// <returns>An initialized <see cref="IHost"/></returns> /// <remarks>Adds basic services to the host such as application lifetime, host environment, and logging.</remarks> public IHost Build() { if (_hostBuilt) { throw new InvalidOperationException(SR.BuildCalled); } _hostBuilt = true; // REVIEW: If we want to raise more events outside of these calls then we will need to // stash this in a field. using DiagnosticListener diagnosticListener = LogHostBuilding(this); // 1.初始化主机(Host)配置 InitializeHostConfiguration(); // 2.初始化 HostingEnvironment InitializeHostingEnvironment(); // 3.初始化 HostBuilderContext InitializeHostBuilderContext(); // 4.初始化应用(App)配置 InitializeAppConfiguration(); // 5.初始化服务并创建 Service Provider InitializeServiceProvider(); return ResolveHost(_appServices, diagnosticListener); } }
首先看一下第一阶段初始化HostConfiguretion
[MemberNotNull(nameof(_hostConfiguration))] private void InitializeHostConfiguration() { IConfigurationBuilder configBuilder = new ConfigurationBuilder() .AddInMemoryCollection(); // Make sure there's some default storage since there are no default providers foreach (Action<IConfigurationBuilder> buildAction in _configureHostConfigActions) { buildAction(configBuilder); }
//此阶段结束,私有属性 _hostConfiguretion已经被创建,在第二个阶段中就可以使用了。 _hostConfiguration = configBuilder.Build(); }
有时候不是我们失去了目标,而是失去了方向。