.NET Core 3.1通用主机原理及使用

一、前言

只是讲asp.net core 3.x通用主机的大致原理,这些东西是通过查看源码以及自己根据经验总结得来的,在文章中不会深入源码,因为个人觉得懂原理就晓得扩展点,后期碰到有需求的时候再仔细去研究源码也不迟。
阅读前你应该先去了解下(推荐博客园老A的博客):

  • asp.net core中的依赖注入、

  • 配置,

讲解的方式是:

  1. 概述

  2. 逐一介绍核心类及扩展方式

  3. 通常我们如何使用

  4. 总结

二、概述

以前的控制台应用程序、winform程序启动时main首先被执行,后续都是我们自己的代码来实现框架和业务上的东东,比如我们要使用配置就ConfigurationManager.AppSettings... 若想使用依赖注入则需要引入第三方框架,比如autofact。asp.net framework时代也类似

在.net core 3.0之前的版本默认使用的是IWebHost,它内部定义了IOC容器(服务注册体现在Startup.ConfigServices),和各种配置源的设置(体现在Program配置主机时),我们后续的Controler、View、包括业务代码可以很容易做依赖注入和获取配置信息(包括运用选项模式)

有时候我们希望写一个服务,但是这个服务并不是用来做api/web,处理http请求的,比如想做一个物联网的后端采集服务,一直等待远端硬件设备提交实时数据过来,后端进行处理。但是又希望使用asp.net core提供的 配置、依赖注入、日志 和其它功能。后来微软就将asp.net core中的这套东西抽离出来了,叫做通用主机,用来承载任何服务,这些自定义服务中就可以很方便地使用配置、依赖注入、日志、和其它功能。现在asp.net core只是由通用主机承载的其中一种服务。

2.1、默认情况下主要的实现思路是:

2.1.1、定义(微软定义好的):

  • 定义HOST,它包含IOC根容器、主机和应用程序的生命周期事件定定义、IHostedService集合(一个实例就是一个服务或者叫应用,asp.net core就是一个这样的实例)

  • 允许调用方提供一堆委托来向IOC中注册服务、和设置主机和应用的“配置源”

  • 提供向主机添加IHostedService的实现对象的方法

  • 允许调用方注册主机和应用在启动和停止阶段触发的相应事件

2.1.2、配置(我们的代码,微软定义很多辅助方法):

  • 创建IHost实例

  • 向Host的IOC容器中注册各种服务

  • 配置主机和应用程序的“配置源

  • 向主机内部添加IHostedService实例(也就是我们最终的服务)

  • 主机和应用的生命周期事件,来实现一些特殊任务

2.1.3、启动阶段(微软定义好的)

  • 上面所谓的配置基本都是通过委托实现的(通常微软提供的各种扩展方法最终也是执行委托),回调这些委托以设置“配置源”和注册服务

  • 最后遍历启动HostedService

  • 在启动过程中还会回调相应的生命周期事件

2.2、啥是应用?

上面提了几次“应用”,现在对于主机来说asp.net core框架就是一个应用、我们上面举例说的"物联网后端服务"是另一个应用。从代码上来说就是一个IHostedService的实现。
主机和应用是一对多的关系,多个应用可以共享主机的信息,如:主机的IOC容器、主机的配置。应用配置。应用当然也可以自己去创建自己的IOC根容器和配置对象

主机配置和应用配置有关系?这两个配置对象都存在于Host中,主机配置是只跟主机相关的配置,应用配置是主机中多个应用共享的配置,如果主机中只有一个应用,那么完全可以拿它做最终的应用配置。另外应用配置包含主机配置

注意:在理解时要记住我们现在的目的是讲解通用主机,意思是可以承载你自己定义的服务的主机,别去想什么mvc controller action 路由之类的

三、核心类

下面分别介绍下主机中的几个核心默认实现类,几乎每个类都有对应的接口,为了缩短篇幅、便于理解就不讲接口了。

3.1、Host

它代表主机,用来宿主(承载)我们应用(一个IHostedService的实现)。
主要包含:日志、主机和应用的生命周期事件、IOC根容器、主机的选项对象、启动停止/停止方法。
接口中只定义了:IOC根容器 + Start + Stop方法
它在Program.Main中被创建、配置和启动

默认实现Microsoft.Extensions.Hosting.Internal.Host,它是一个internal的类,这个主机将来被启动时:

  • 触发主机的WaitForStartAsync事件

  • 逐一启动主机内部的hostedService

  • 触发_applicationLifetime?.NotifyStarted();事件

  • 停止时就反过来,先逐一停止hostedService,触发响应事件、最后停止主机

扩展:

因为默认Host是internal修饰的,所以无法继承

  • 自定义实现IHost;(这不说了,你可以随心所欲)

  • 订阅主机和应用的生命周期事件(实现IHostLifetime、IHostApplicationLifetime并添加到IOC容器)

大部分情况下方式2实现起来更容易也更常见

提一嘴,asp.net core 3.x现在也是使用的这个默认主机,只是在上面做了根web相关的配置,将在下一篇讲解

3.2、HostBuilder

Host的职责只是完成主机该有的功能,那么它的创建及配置最好另外定义一个类HostBuilder,它是Host的创建器(工厂),我们通常

  • 在系统启动时(Program.Man)先创建HostBuilder,

  • 然后进行配置(向IOC容器注册服务,设置主机和应用的"配置源"),

  • 最后调用Build方法生成我们最终的Host

通过接口IHostBuilder源码可以初略看出它(通过委托的方式)提供以下功能

  • 设置主机和应用的“配置源”

  • 配置IOC容器本身

  • 想IOC容器添加服务

  • 创建Host

  • 有个Properties属性,是个字典类型,可以在构建Host的多个步骤中传递数据

扩展:

对于我们使用者来说主要是通过它的方法向内部塞入各种委托,以达到向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是如何承载到通用主机上的

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/312386.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

火焰效果材质实现_「游戏开发」使用Unity实现魔法火焰效果

*本文转载自公众号“Unity官方平台”。本文由视觉效果艺术家Evgeny Starostin分享如何使用Unity制作魔法火焰效果的过程,让我们一起学习和制作魔法火焰吧。下面是魔法火焰效果图。项目下载本文提供项目工程及着色器下载。本文为转载文章,请关注公众号“U…

激光炸弹(二维前缀和问题)

2020.12.30开始学习AcWing算法《算法竞赛进阶指南》&#xff1b; 上传博客方便复习。 //Wecccccccc //2021.1.2 #include <iostream> using namespace std; const int N 5010; int mp[N][N]; int main() {int n,m,k,r,x,y,w;cin>>k>>r;r min(r,5001);n m …

错误使用.Net Redis客户端CSRedisCore,自己挖坑自己填

本文2019年中原创首发于博客园&#xff0c;当时使用CSRedisCore的排障思路引起很大反响&#xff0c;当时被张队公众号翻牌&#xff0c;本次转回公号。背景上次Redis MQ分布式改造之后&#xff0c;编排的容器稳定运行一个多月&#xff0c;昨天突然收到ETL端同事通知&#xff0c;…

最佳牛围栏(二分)

2020.12.30开始学习AcWing算法《算法竞赛进阶指南》&#xff1b; 上传博客方便复习。 #include <iostream> using namespace std; #include <algorithm> const int N 100001; int n, m; int cow[N]; double sum[N];bool check (double ave) {for (int i 1; i <…

IHostingEnvironment VS IHostEnvironment - .NET Core 3.0中的废弃类型

原文&#xff1a;https://andrewlock.net/ihostingenvironment-vs-ihost-environment-obsolete-types-in-net-core-3/作者&#xff1a;Andrew Lock译者&#xff1a;Lamond Lu本篇是如何升级到ASP.NET Core 3.0系列文章的第二篇。Part 1 - 将.NET Standard 2.0 类库转换为.NET C…

【敏捷案例】老板太外行,朝令夕改!要不要拿了年终奖就撤?

快到春节了&#xff0c;不知道有多少人在等着春节后跳槽&#xff0c;想跳槽的原因也很多&#xff0c;其中一个比较普遍的原因是和老板聊不到一块儿去。前两天&#xff0c;有个学员咨询了我们一个问题&#xff0c;因为这个问题比较普遍&#xff0c;拿出来和大家一起讨论一下~提出…

【2019总结篇】谈谈数字化时代,ERP如何坐稳数字化底座

源宝导读&#xff1a;面向未来&#xff0c;信息化、在线化、智能化&#xff0c;开放应该是数字化转型的核心要素&#xff01;本文将重点介绍2019年明源云ERP开放平台在推进数字化转型中的核心技术层面的实践成果。一、前言面向未来&#xff0c;信息化、在线化、智能化&#xff…

dotNetCore操作Redis(含CentOS7哨兵模式部署)

现在说到使用缓存中间件基本就是 Redis 了&#xff0c;通常开发环境或测试环境部署一个单机版就可以运行了&#xff0c;但要上生产环境还需要进行高可用的方式来部署&#xff0c;本文说说在 CentOS7 中 Redis 高可用的部署以及在 dotNetCore 中怎样调用。环境CentOS&#xff1a…

php和mysql一键安装包_iis+php+mysql一键安装教程和安装包

导读&#xff1a;iis上mysqlphp一键安装 很多用vps的朋友&#xff0c;在windons系统iis上配置mysqlphp环境的时候都非常的头痛&#xff0c;过程非常复杂和麻烦&#xff0c;所以我们推荐大家用mysqlphp一键安装包&#xff1a; 1、下载mysqlphp一键安装包&#xff0c;安装包下载地…

程序员过关斩将--自定义线程池来实现文档转码

背景我司在很久之前&#xff0c;一位很久之前的同事写过一个文档转图片的服务&#xff0c;具体业务如下&#xff1a;1. 用户在客户端上传文档&#xff0c;可以是ppt&#xff0c;word&#xff0c;pdf 等格式&#xff0c;用户上传完成可以在客户端预览上传的文档&#xff0c;预览…

UnitTest in .NET(Part 4)

Photo &#xff1a;Unit Test in Visual Studio文 | Edison Zhou上一篇我们学习了如何使用模拟对象进行交互测试。这一篇我们则会进一步使用隔离框架支持适应未来和可用性的功能。为何使用模拟框架&#xff1f; 对于复杂的交互场景&#xff0c;可能手工编写模拟对象和存根就会变…

Xamarin.Forms弹出对话框插件

微信公众号&#xff1a;Dotnet9&#xff0c;网站&#xff1a;Dotnet9&#xff0c;问题或建议&#xff0c;请网站留言&#xff1b;如果您觉得Dotnet9对您有帮助&#xff0c;欢迎赞赏。Dotnet9.com内容目录实现效果业务场景编码实现本文参考源码下载1.实现效果弹出动画 2.业务场景…

Pycharm安装第三方库

转载地址&#xff1a; https://www.cnblogs.com/bwjblogs/p/12839463.html 今晚想安装一些第三方库但是pip版本低&#xff0c;安装一直报错&#xff0c;输入升级的命令也一直不行。于是在pycharm上安装&#xff0c;但是还是一直失败&#xff0c;下面提出解决办法。 然后在搜索…

CAP 3.0 版本正式发布

前言大家好&#xff0c;我们很高兴宣布 CAP 发布了 3.0 版本正式版。自从上次 CAP 2.6 版本发布 以来&#xff0c;已经过去了几个月的时间&#xff0c;关注的朋友可能知道&#xff0c;在这几个月的时间里&#xff0c;也发布了几个预览版的 3.0 版本的NuGet包。3.0 是一个主要版…

mysql字符集变为gbk_MYSQL数据库默认latin1字符集转换为GBK或UTF8

可以采用下面的方法latin1字符集转换为gbk字符集或utf8字符集。具体的转换步骤如下&#xff1a;一、latin1转gbk1、导出数据库mysqldump --default-character-setlatin1 -h 数据库连接ip -u root -P 3306 -p数据库密码 db_name table_name > /usr/home/test/table_name.sql2…

微服务统计,分析,图表,监控一体化的HttpReports项目在.Net Core 中的使用

简单介绍HttpReports 是 .Net Core 下的一个Web项目, 适用于WebAPI&#xff0c;Ocelot网关应用&#xff0c;MVC项目&#xff0c;非常适合针对微服务应用使用&#xff0c;通过中间件的形式集成到您的项目中&#xff0c;可以让开发人员快速的搭建出一个 数据统计&#xff0c;分析…

查看node的位置_升级Node版本RN项目运行报错cb.apply is not a function

今日打算安装一下ReactNative官方推荐的脚手架工具Ignite。infinitered/ignite​github.comIgnite是一套整合了 Redux 以及一些常见 UI 组件的脚手架。它带有一个命令行可以生成 app、组件或是容器。在安装的过程中&#xff0c;提示当前系统安装的node版本过低&#xff0c;无法…

C++构造函数调用规则

1.拷贝函数的值拷贝&#xff1a; #include <iostream> using namespace std;//构造函数的调用规则&#xff1a; //1,创建一个类&#xff0c;C编译器会给每个类都添加至少3个函数 //默认函数(空实现)&#xff0c;析构函数(空实现)&#xff0c;拷贝函数(值拷贝)class Pers…

HTTP Strict Transport Security (HSTS) in ASP.NET Core

本文是《2020年了&#xff0c;再不会HTTPS就老了》的后篇&#xff0c;本文着重聊一聊HTTP Strict Transport Security协议的概念和应用。启用 HTTPS 还不够安全现在很多站点通过HTTPS对外提供服务&#xff0c;用户在访问某站点&#xff0c;往往会直接输入站点域名&#xff08;b…

mysql支持的平台和操作系统_MySQL 数据库所支持的操作系统_MySQL

MySQL数据库所支持的操作系统&#xff1a;我们使用GNU Autoconf&#xff0c;因此将MySQL移植到所有使用Posix线程和C编译器的现代系统是可能的。(要求服务器支持线程。如果只是编译客户端代码&#xff0c;则只需要C编译器)。我们主要在Linux(SuSE和Red Hat)、FreeBSD和Sun Sola…