.NET Core中间件的注册和管道的构建(3) ---- 使用Map/MapWhen扩展方法

0x00 为什么需要Map(MapWhen)扩展

如果业务逻辑比较简单的话,一条主管道就够了,确实用不到Map。不过当业务逻辑比较复杂的时候,有时候我们可能希望根据情况的不同使用特殊的一组中间件来处理HttpContext。这种情况下如果只用一条管道,处理起来会非常麻烦和混乱。此时就可以使用Map/MapWhen建立一个分支管道,当条件符合我们的设定时,由这个分支管道来处理HttpContext。使用Map/MapWhen添加分支管道是很容易的,只要提供合适跳转到分支管道的判断逻辑,以及分支管道的构建方法就可以了。

0x01 Map扩展的原理

前一篇文章中我们说过,中间件的注册和管道的构建都是通过ApplicationBuilder进行的。因此要构建一个分支管道,需要一个新的ApplicationBuilder,并用它来注册中间件,构建管道。为了在分支管道中也能够共享我们在当前ApplicationBuilder中注册的服务(或是说共享依赖注入容器,当然共享的并不止这些),在创建新的ApplicationBuilder时并不是直接new一个全新的,而是调用当前ApplicationBuilder的New方法在当前的基础上创建新的,共享了当前ApplicationBuilder的Properties(其中包含了依赖注入容器)。

在使用Map注册中间件时我们会传入一个Action<IApplicationBuilder>参数,它的作用就是,当我们创建了新的ApplicationBuilder后,使用这个方法对其进行各种设置,最重要的就是在新的ApplicationBuilder上注册分支管道的中间件。配置完成后调用分支ApplicationBuilder的Builder方法构建管道,并把第一个中间件保存下来作为分支管道的入口。

在使用Map注册中间件时传入了一个PathString参数,PathString对象我们可以简单地认为是string。它用于记录HttpContext.HttpRequest.Path中要匹配的区段(Segment)。这个字符串参数结尾不能是“/”。如果匹配成功则进入分支管道,匹配失则败继续当前管道。

新构建的管道和用于匹配的字符串保存为MapOptions对象,保存了Map规则和分支管道的入口。之后构建MapMiddleware对象,并把它的Invoke方法包装为RequestDelegate,使用当前ApplicationBuilder的Use方法注册中间件。

下面是Map扩展方法:

下面是MapMiddleware的Invoke方法

0x02 MapWhen扩展的原理

Map主要通过URL中的Path来判断是否需要进入分支管道,但有时候我们很可能会有别的需求,例如我想对所有Method为DELETE的请求用特殊管道处理。这时候就需要用MapWhen了。MapWhen是一种通用的Map,可以由使用者来决定什么时候进入分支管道什么时候不进入。可以说Map是MapWhen的一种情况,因为这种情况太常见了,所以官方实现了一个。这样看来MapWhen就很简单了,在Map中我们传入参数PathString来进行HttpRequest.Path的匹配,在MapWhen中我们传入Func<HttpContext,bool>参数,有我们自行指定,当返回true时进入分支管道,返回false则继续当前管道。

下面是MapWhen扩展方法:

下面是MapWhenMiddleware的Invoke方法:

0x03 顺便提一下Run扩展

还有一个注册中间件的扩展方法是Run,因为非常简单,所以在最后提一下。Run就是用Use注册一个中间件,最后不调用下一个中间件直接返回。所以使用Run扩展方法注册中间件永远都是直接返回的,后面的中间件都不会被调用。

0x04 写在最后

Map/MapWhen和Run都很简单就不写测试了。到此为止中间件的注册和管道的构建主题就写完了。刚开始是出于对中间件有些地方的迷惑开始的,搞明白了后本想着写一篇博客分享下自己的心得,没想到越写越多,一篇分成两篇,到现在写了三篇。我这些也只是写了些大概,很多细节没写到,有兴趣的可以去github上看一下代码,管道和中间件相关的都在这个仓库:https://github.com/aspnet/HttpAbstractions。

0x05 相关文章

.NET Core中间件的注册和管道的构建(1)---- 注册和构建原理

.NET Core中间件的注册和管道的构建(2)---- 用UseMiddleware扩展方法注册中间件类

.NET Core中间件的注册和管道的构建(3) ---- 使用Map/MapWhen扩展方法

.NET Core中间件的注册和管道的构建(3) ---- 使用Map/MapWhen扩展方法的更多相关文章

  1. .NET Core中间件的注册和管道的构建(2)---- 用UseMiddleware扩展方法注册中间件类

    .NET Core中间件的注册和管道的构建(2)---- 用UseMiddleware扩展方法注册中间件类 0x00 为什么要引入扩展方法 有的中间件功能比较简单,有的则比较复杂,并且依赖其它组件.除 ...

  2. .NET Core中间件的注册和管道的构建(1)---- 注册和构建原理

    .NET Core中间件的注册和管道的构建(1)---- 注册和构建原理 0x00 问题的产生 管道是.NET Core中非常关键的一个概念,很多重要的组件都以中间件的形式存在,包括权限管理.会话管理 ...

  3. 用UseMiddleware扩展方法注册中间件类

    用UseMiddleware扩展方法注册中间件类 .NET Core中间件的注册和管道的构建(2)---- 用UseMiddleware扩展方法注册中间件类 0x00 为什么要引入扩展方法 有的中间件 ...

  4. ASP.NET Core 1.0中的管道-中间件模式

    ASP.NET Core 1.0借鉴了Katana项目的管道设计(Pipeline).日志记录.用户认证.MVC等模块都以中间件(Middleware)的方式注册在管道中.显而易见这样的设计非常松耦合 ...

  5. Core 1.0中的管道-中间件模式

    ASP.NET Core 1.0中的管道-中间件模式 SP.NET Core 1.0借鉴了Katana项目的管道设计(Pipeline).日志记录.用户认证.MVC等模块都以中间件(Middlewar ...

  6. asp.net core mvc剖析:处理管道构建

    在启动流程文章中提到,在WebHost类中,通过BuildApplication完成http请求处理管道的构建.在来看一下代码: ...... //这个调用的就是Startup.cs类中的Config ...

  7. ASP.NET Core MVC 2.x 全面教程_ASP.NET Core MVC 03. 服务注册和管道

    ASP.NET Core MVC 2.x 全面教程_ASP.NET Core MVC 03. 服务注册和管道 语雀: https://www.yuque.com/yuejiangliu/dotnet/ ...

  8. .net core 中间件管道底层剖析

    .net core 管道(Pipeline)是什么? 由上图可以看出,.net core 管道是请求抵达服务器到响应结果返回的中间的一系列的处理过程,如果我们简化一下成下图来看的话,.net core ...

  9. ASP.NET Core - 中间件与管道(1)

    今天来讨论一个ASP.NET Core 很重要概念管道和中间件,在ASP.NET Core中,针对HTTP请求采用pipeline也就是通常说的管道方式来处理,而管道容器内可以挂载很多中间件(处理逻辑 ...

随机推荐

  1. 【AR实验室】ARToolKit之Example篇

    0x00 - 前言 PS : 我突然意识到ARToolKit本质可能就是一个可以实时求解相机内外参的解决方案. 拿到一个新的SDK,90%的人应该都会先跑一下Example.拿到ARToolKit的S ...

  2. java中的锁

    java中有哪些锁 这个问题在我看了一遍<java并发编程>后尽然无法回答,说明自己对于锁的概念了解的不够.于是再次翻看了一下书里的内容,突然有点打开脑门的感觉.看来确实是要学习的最好方式 ...

  3. .NET Core系列 :4 测试

    2016.6.27 微软已经正式发布了.NET Core 1.0 RTM,但是工具链还是预览版,同样的大量的开源测试库也都是至少发布了Alpha测试版支持.NET Core, 这篇文章 The Sta ...

  4. .NET Core中间件的注册和管道的构建(2)---- 用UseMiddleware扩展方法注册中间件类

    .NET Core中间件的注册和管道的构建(2)---- 用UseMiddleware扩展方法注册中间件类 0x00 为什么要引入扩展方法 有的中间件功能比较简单,有的则比较复杂,并且依赖其它组件.除 ...

  5. Unity游戏内版本更新

    最近研究了一下游戏内apk包更新的方法. ios对于应用的管理比较严格,除非热更新脚本,不太可能做到端内大版本包的更新.然而安卓端则没有此限制.因此可以做到不跳到网页或应用商店,就覆盖更新apk包. ...

  6. Android Ormlite 学习笔记1 -- 基础

    Ormlite 是一个开源Java数据实体映射框架.其中依赖2个核心类库: 1.ormlite-android-4.48.jar 2.ormlite-core-4.48.jar 新建项目,引用上面2个 ...

  7. 利用XAG在RAC环境下实现GoldenGate自动Failover

    概述 在RAC环境下配置OGG,要想实现RAC节点故障时,OGG能自动的failover到正常节点,要保证两点: 1. OGG的checkpoint,trail,BR文件放置在共享的集群文件系统上,R ...

  8. EF上下文对象线程内唯一性与优化

    在一次请求中,即一个线程内,若是用到EF数据上下文对象,就创建一个,这也加是很多人的代码中习惯在使用上下文对象时,习惯将对象建立在using中,也是为了尽早释放上下文对象, 但是如果有一个业务逻辑调用 ...

  9. springmvc的拦截器

    什么是拦截器                                                         java里的拦截器是动态拦截action调用的对象.它提供了一种机制可以使 ...

  10. Exception in thread "main" java.lang.NoSuchMethodError: org.objectweb.asm.ClassWriter.<init>(I)V

    在学习CGlib动态代理时,遇到如下错误: Exception in thread "main" java.lang.NoSuchMethodError: org.objectwe ...