重新整理 .net core 实践篇————配置应用[一] (3)

以上都是推论。那么直接看源码,因为是构建者模式,所以直接看build。

public IHost Build() { if (_hostBuilt) { throw new InvalidOperationException("Build can only be called once."); } _hostBuilt = true; BuildHostConfiguration(); CreateHostingEnvironment(); CreateHostBuilderContext(); BuildAppConfiguration(); CreateServiceProvider(); return _appServices.GetRequiredService<IHost>(); }

上面的顺序和猜想是一致的。

这里看下BuildHostConfiguration:

private List<Action<IConfigurationBuilder>> _configureHostConfigActions = new List<Action<IConfigurationBuilder>>(); private void BuildHostConfiguration() { var configBuilder = new ConfigurationBuilder() .AddInMemoryCollection(); // Make sure there's some default storage since there are no default providers foreach (var buildAction in _configureHostConfigActions) { buildAction(configBuilder); } _hostConfiguration = configBuilder.Build(); }

那么其实我们按照这种配置,那么其实我们的ConfigureHostConfiguration全部方法都是在_configureHostConfigActions 中,到了builder 的时候就按照我们的注册顺序执行。

那么这里就能解释ConfigureWebHostDefaults 不管顺序都是在最前面,而里面startup的顺序确不一样。

代码解释一波:

public static IHostBuilder ConfigureWebHostDefaults(this IHostBuilder builder, Action<IWebHostBuilder> configure) { return builder.ConfigureWebHost(webHostBuilder => { WebHost.ConfigureWebDefaults(webHostBuilder); configure(webHostBuilder); }); }

ConfigureWebHostDefaults 立即执行,那么log自然就先打印出来了,而其他几个都是延迟执行的。他们的执行顺序和注册顺序有关。

最后再解释一下,webBuilder.UseStartup(); 到底做了什么?

public static IWebHostBuilder UseStartup(this IWebHostBuilder hostBuilder, Type startupType) { var startupAssemblyName = startupType.GetTypeInfo().Assembly.GetName().Name; hostBuilder.UseSetting(WebHostDefaults.ApplicationKey, startupAssemblyName); // Light up the GenericWebHostBuilder implementation if (hostBuilder is ISupportsStartup supportsStartup) { return supportsStartup.UseStartup(startupType); } return hostBuilder .ConfigureServices(services => { if (typeof(IStartup).GetTypeInfo().IsAssignableFrom(startupType.GetTypeInfo())) { services.AddSingleton(typeof(IStartup), startupType); } else { services.AddSingleton(typeof(IStartup), sp => { var hostingEnvironment = sp.GetRequiredService<IHostEnvironment>(); return new ConventionBasedStartup(StartupLoader.LoadMethods(sp, startupType, hostingEnvironment.EnvironmentName)); }); } }); }

解释一下IsAssignableFrom:

bool res = {TypeA}.IsAssignableFrom({TypeB}) ; 如果TypeA和TypeB类型一样则返回true; 如果TypeA是TypeB的父类则返回true; 如果TypeB实现了接口TypeA则返回true;

可以看到这里做的是一个IStartup 到 Startup的一个依赖注入,且是单例模式,所以肯定的是Startup 里面的方法会在ConfigureHostConfiguration、ConfigureAppConfiguration之后执行,因为其在ConfigureServices 才开始注入依赖的。

因为是应用篇,单纯是一些应用需要知道的,所以比较粗糙,具体的详细在原理篇介绍了。上述只是个人的理解,如果错误,望请指点,谢谢。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zypffp.html