12.24 (Core管道&中间件&依赖注入+琐碎笔记)

​emmmm,其实本来想发服务器部署那一篇的笔记的,可奈何折腾了好多天的linux,部署还是有一小丢丢不完美(我还是想完美一些)所以,今天先把core的这篇主线给更新了。

 

NET Core 管道机制(自己画的将就着看吧)

 

 

v2-e01af13a7b029440dbba372832eae408_b.jpg

 

net core默认情况下是通过Startup类来配置服务和管道的。

 

如上图所示:整个应用如同一个管道,请求进来,经过一个个中间件,最后到达我们的路由,控制器,经过处理,并将结果一步步进行返回。

 

我们可以将这个管道想象成一个大商场,商场有一个进口(Request)和一个出口(Response),每一个人都是一次请求,经过进口,通过安检(认证),给予你能进入哪些商店(中间件)的权利(授权)。相当于你进去之后,给你发了一张临时的身份识别卡,卡上面有你的全部信息,这个卡可以看做是HttpContext。授权之后,假定你要进入未经授权的商店,肯定会被拒绝,因为你一在他们商店刷卡,就会显示你没有进入此地的权利。

 

你路过了鲜花店(Middleware),假若你有权利进入,你可以选择进去买鲜花,也可以选择不买。你可以转了一圈商场什么都不做,按原路返回,也可以走到半中腰就回去了。

 

下面来看一下Startup类的配置。

 

其中有两个核心的方法。一个是ConfigureServices(服务配置类),一个是Configure(配置类)。

 

前面有一篇IoC和DI中我写过,在这里再复习一下。


ConfigureServices是用来配置各种各样的服务的,比如认证这个中间件,他是你进入商场的安检关卡,这里就是给安检人员配备相应的设备,比如电脑,身份识别卡,再或者对讲机、警棍等等。没有这些设备,我应用的服务中间件如何能正常工作呢?这里的服务配置添加,不分先后顺序。因为不论是先给警察配好警棍,还是给清洁阿姨准备扫帚。这些都是准备工作,还没到真正服务的时候,所以不分先后顺序。

 

而Configure中的配置的中间件是区分先后顺序的。比如,先放好静态文件服务、路由服务、之后授权、认证、xxx服务、最后到endoptions控制器,其实控制器也是一个大的中间件,它里面有各种服务,比如过滤器等等。

 

 

v2-52118e4ef3150dc30e6149b7ee5882d3_b.jpg

 

 

中间件是什么呢,如我开头图示,它是一种装配到应用程序管道以处理请求和响应的软件,每个组件可以:

 

《1》选择是否将请求传递到管道中的下一个组件。

《2》可在调用管道中的下一个组件前后执行工作。即中间件的事前逻辑和事后逻辑。

 

当然,如果出现错误,它不会再进行下一个组件,而是原路返回。

 

中间件的写法:

(1)命名:类名后缀:Middleware

(2)构造函数:注入RequestDelegate next

(3)逻辑 异步 命名 :async Task Invoke(HttpContext context)

 

接下来,我们自己建一个中间件。先说下思路:建一个可以设置全局变量的中间件,当请求经过中间件,分析请求,并将参数解析出来之后,赋值给全局变量。

 

新建类:SetOptionMiddleware,添加构造函数和方法

 

 

 

v2-b73d7e7ac16f0d534b3db2cca181e673_b.jpg

 

 

至于为什么这样写?没有为什么,这是net core的约定,就是要这么写,它才是一个中间件。构造函数那里我还注入了一个全局类,这个IOptions<class> 这个东西,可以认为是一个公共的对象,它可以从头传到尾,供中间件使用。下图是CommonOption类

 

 

 

v2-48898a7e18a214e5ea95ef6c64f09e74_b.jpg

 

 

Invoke的方法如下:

 

 

v2-119b059c49d81c55c5bdb5373e18fbe3_b.jpg

 

解析请求头上附加的参数option,若存在,在将其赋值给全局变量,最后在前端打印出我们传的参数。

 

接下来,需要在Startup中,添加对此中间件的使用,由于其并没有依赖任何其他外部的工具或服务,所以并不需要为其依赖注入或者配备其他的服务。只需在Configure里添加即可,如下图:

 

 

 

v2-91b2ccc4c53ce7554f3eb56f0fbd6ed7_b.jpg

 

但是看起来好像和下面的其他的中间件有点区别,为了遵循微软的规范,我决定学它的写法emmmm(其实我觉得我这样写也还行吧)

 

新建一个扩展类,如下图:

 

 

v2-a1e756e3fa71d9789782694da0ce6b7b_b.jpg

 

 

然后,就可以使用:

 

 

v2-8209b56f9c20b6615ba530162be95c93_b.jpg

 

 

接下来,我们在中间件上打上断点,观察变量的变化:

 

在url上加上参数:

 

 

v2-0ee23f39e8316f57b6e18e1410fff8d5_b.jpg

 

 

 

v2-0cb05b877d9f3408764a7133534076a0_b.jpg

 

如上图所示:可以看到,在给全局对象赋值前,我们的option(请求的参数)是 《巴黎圣母院》 ,全局对象的值是 默认值

继续调试:发现,值有了变化:

 

 

v2-df7097aaa0b1a68bb05ff79efc8b8778_b.jpg

 

 

继续之后,前端的视图也输出了我们的文本内容,而非默认的Index视图内容

 

 

v2-6fbf9fcd2d35d5ce9b79093c276664f2_b.jpg

 

 

emm,今天粗略的中间件就到这里了,接下来是依赖注入:

 

依赖注入,这个已经是老生常谈了。但还是复习一下,温故而知新,可以为师矣嘛。和之前不一样的是,这次会使用代码示例来研究依赖注入微软源生的三大生命周期(上次粗略的说了下,而且着重用的是第三方IoC:Autofac)

 

依赖注入是实现松散耦合技术,将依赖关系注入到容器当中。在ASP .NET Core中容器为IServiceProvider接口表示,任何人都可以实现自己的容器。最好使用构造函数注入,第三方IoC容器有:UnityIoC,AutoFac等等。

 

三大生命周期:

(1)多例模式 Transient。每解析一次接口,就会实例化一个对象。每次对象都是唯一且不同的。 每次解析请求,实例的都是一个全新的对象。

 

(2)Scoped 英文释为范围,区域。第一次请求,它会实例出一个对象:

IA a=new A();并缓存下来,接下来的每一次请求,会判断是否是同一个HttpContext,如若是同一个,那么它仍然返回这个a对象。

 

这里解释下,什么叫一次请求。同一次请求,它的HttpContext肯定是同一个,所以返回的都是a。这里Scoped其实就是一次http请求的作用域,同一次请求,可能多次请求其他的服务,也可能多次请求同一个控制器,只是这个人进了商场买东西,不管做什么,还是这个人。 但是它一旦出了这个商场(结束了本次http请求)再次进入商场,就是新的请求了,就需要重新过安检。(虽然还是那个人)

 

(3)单例模式:singleton 只要服务器不嗝屁,不管解析多少次接口,拿到的都是a。换句话说就是,只要皇帝不死,太子一直是太子!从商场建成开业到商场倒闭关门,此次程序服务过程中,单例返回的始终是这个a。

 

下面通过代码来践行验证:

新建一个接口,和实现。里面放一个返回guid的方法。如下图:

 

 

 

v2-387e7080fd46978b049f3fae3f9e4e81_b.jpg

 

接着我们在Startup中依赖注入服务。

 

(1)先使用多例模式

 

 

v2-56d8759397bf75f6215098f46a203e93_b.jpg

 

控制器和视图如下:

 

 

v2-24edf8c1710cdcd01428706ca3842c04_b.jpg

 

 

 

v2-217145e9eda70415352135e6e4158ee9_b.jpg

 

 

测试结果如下

 

 

v2-7927f638f317bc667f10540fb3dd2110_b.jpg

 

刷新再尝试:

 

 

v2-4ae5af86571a3614d0da628a211cea97_b.jpg

 

结果四次解析,均不同,验证多例模式:每次解析,实例化的对象都不同。

 

(2)接着使用Scoped,配置:

 

 

v2-0efc764dc3590dbc3f2fce72e448f1fa_b.jpg

 

第一次http请求如下图:

 

 

v2-f621d3ff9c5df516eb7ab37ab4c1f1c0_b.jpg

 

第二次请求:

 

 

v2-4ef866455d4199f788435c4226e9cf5e_b.jpg

 

两次请求,在同一次请求有效范围内,均产生相同的实例对象。

 

(3)单例模式

配置如下:

 

 

v2-b75c302f049ecab62a4d78ba3e73431f_b.jpg

 

测试如下:

 

 

v2-c0d88b03cf183ae4684425ba14c8efa2_b.jpg

 

发现,不管刷新多少次,始终返回如上内容对象。证明:单例模式下,从应用程序启动到结束,不管请求多少次,解析多少次接口,始终返回同一对象。

 


 

下面是琐碎笔记内容:

(1)出现 已添加了具有相同键的项 错误,前端调试传参无误,后端不进入断点。 原因:后台的接收参数的model可能出现了同样的参数(大小写不一样但是参数一样。C#后台区分大小写,但是前端传过来的参数传输的时候不识别大小写,它给后端,就不知道给谁了。

 

(2)出现错误 xxxxx could not be located 原因:服务或者类的构造函数没有加public修饰符,导致容器没有足够的访问权限,不能加载,报错。

 

(3)git命令复习:

git checkout -b name1:创建分支name1并切换到分支name1上,相当于两条命令:git branch name1 git checkout name1 两条命令

 

在另外一个分支做完之后,commit之后,切换到master分支

git checkout master

之后合并分支

git merge 旧的分支

 

(4)swagger 配置好之后,访问swaager 报无法发现 ....json 文件

原因是中间件位置没有使用swagger。有三个地方需要添加,第一,configureservice那添加跟服务,并配置好文档。 第二个,configure那使用swagger,使用swaggerUI

 

如果报500错误,其中一个原因是,你可能没有给你的动作方法加上谓词,因为swagger需要知道你的接口方法是什么httpmethod

 

(5)几个后缀名文件识别:

bat 批处理程序 bak mssql数据库的备份文件

dmp oracle数据库的备份文件

 

(6)VS中找到所有的变量,一次性更换到所有的名字

ctrl+f ctrl+h

 

(7)快速实现接口:alt+enter

 

(8)调试-窗口-即时 窗口 可以实时观察调试时的变量的值的变化。

 

好了,今天笔记到这里结束了,有交流的请留言,下次再见。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值