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

2019-12-24  本文已影响0人  我是大成子

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

中间件的写法:

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

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

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

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

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

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

Invoke的方法如下:

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

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

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

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

然后,就可以使用:

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

在url上加上参数:

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

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

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

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的方法。如下图:

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

(1)先使用多例模式

控制器和视图如下:

测试结果如下

刷新再尝试:

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

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

第一次http请求如下图:

第二次请求:

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

(3)单例模式

配置如下:

测试如下:

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

下面是琐碎笔记内容:

(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)调试-窗口-即时 窗口    可以实时观察调试时的变量的值的变化。

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

欢迎关注我的个人微信公众号:dotNET学习天地

上一篇下一篇

猜你喜欢

热点阅读