对于我们使用者来说主要是通过它的方法向内部塞入各种委托,以达到向IOC容器注册服务和设置主机和应用的“配置源”
也可以但估计很少去实现主机的IHostBuilder;继承HostBuilder意义也不大,因为它没有提供抽象和虚方法
默认Build流程
初始化主机配置对象IConfiguration,主要是回调,主机没有做其它的
初始化主机环境对象_hostingEnvironment
应用程序名字从上一步的主机配置里来
环境名(开发?调试?)从配置里来,若没有则默认是生产模式"Production"
内容根也从配置里来,若没有则是当前程序路径
根据内容跟创建一个ContentRootFileProvider 实现类是PhysicalFileProvider
初始化HostBuilderContext,根据上面的配置和环境创建这个上下文(这里只是暂时用的主机配置,下面会被替换成应用的配置)
初始化应用配置
以上面的内容根作为配置查找的根(若将来提供物理文件作为配置源时需要此属性)
将主机配置塞入这个应用配置,所以应用配置=主机配置+回调后的配置
最后将HostBuilderContext的Configuration替换为此配置对象
创建IOC容器
创建ServiceCollection,并将上面的几个对象以单利模式放入进去
还要放入IHostApplicationLifetime和IHostLifetime和Host
开启选项模式,注册日志
回调configureServicesAction
调用工厂_serviceProviderFactory创建ServiceProvider
回调_configureContainerActions
最后返回容器
调用容器解析并返回Host
3.3、HostBuilder的工厂方法Host.CreateDefaultBuilder上面有了Host,也有了对应的创建器HostBuilder,为啥还要再提供一个工厂方法呢?
因为职责分离原则,Host只负责承载应用并提供容器和设置配置源;HostBuilder只是负责配置并创建Host,尽可能提供一些默认值(前提时将来调用方未提供那些参数)。此时我们可以直接用HostBuilder来创建Host并启动它,但别忘了.net core是一个通用框架,它应提供一个更简洁的方式来创建最终的Host,因此它提供了静态方法Host.CreateDefaultBuilder,它尽可能提供更多的默认值,核心任务如下:
new HostBuilder
设置程序的当前目录为内容根
为主机配置 设置 环境变量作为配置源(只关注前缀DOTNET_的环境变量)
为应用配置设置 以“appsettings.json”和“appsettings.{env.EnvironmentName}.json”作为配置源;同时也将环境变量加入到应用的配置源;最后将命令行参数加入到配置源
配置日志
若是开发模式,还会配置依赖注入的范围验证
四、从使用者的角度来说通过自定义实现IHostedService的类来实现我们的服务,我们的服务中的类可以
直接使用依赖注入,
也可以通过依赖注入获取主机配置和全局应用配置对象,或者更方便的是进一步使用选项模式
我们也可以注入日志记录器
由于主机创建过程的相关数据几乎都放进了IOC容器中,因此我们也可以通过依赖注入拿到
其它...
在Program.man调用Host.CreateDefaultBuilder,如果需要,提供相应的委托来注册服务和设置主机和应用的“配置源”,最好是通过相关扩展方法和自定义扩展方法。重点是记得注入我们自己的服务实现类
五、总结.net core为我们提供了新的承载应用(包括但不仅限于asp.net core)的方式-->通用主机,通过它我们可以很容易的在自己的应用中使用依赖注入、配置、日志等,你可以发挥想象实现很多牛B的框架。
asp.net core 3.x开始默认也是使用它来承载的
核心的Host、HostBuilder、Host.CreateDefaultBuilder实现了通用主机,并提供了扩展点
最后我想说如果在.net core上提供一个默认的aop方案就更完美了。
下一篇试试说下asp.net core是如何承载到通用主机上的