前言

ASP.NET Core的Middleware(中间件)就是使用了管道模式:

Request(请求)在管道中传递,依次经过管道中的每一个MiddleWare进行处理。

MiddleWare就像一层层的“滤网”,过滤所有的请求和响应。

这种模式的好处在于,分离关注点。比如验证用户、记录访问日志,可以将这些任务分解到不同MiddleWare中,互相解耦。

既然ASP.NET Core已经实现了管道模式,为什么还要在业务层实现一遍呢?

原因

我觉得可以分为2方面考虑:

  • 与顶级框架解耦,不能保证应用程序代码始终运行在ASP.NET Core下,如果将业务迁移到WPF,记录访问日志这类放在管道中的功能还是需要实现

  • 同时支持不同来源请求,请求可能来自于Web API,也可能来自于Windows Service定时调用,但业务层处理逻辑应保持一样

因此,ASP.NET Core框架应该只用于接收输入和返回输出,而在业务层实现管道模式。

定义API的最佳实践

在《定义API的最佳实践MediatR类库实现Controller方法,将业务逻辑和Controller进行隔离。

示例代码如下:

[HttpGet]
public async Task<string> Demo([FromQuery] DemoQuery request)
{return await _mediator.Send(request);
}public class DemoQuery : IRequest<string>
{public string Name { get; set; }
}public class DemoQueryHandler : IRequestHandler<DemoQuery, string>
{ public async Task<string> Handle(DemoQuery request, CancellationToken cancellationToken){Console.WriteLine("DemoQueryHandler执行");return request.Name;}
}

而MediatR不仅仅是一个简单的中介模式实现,它还提供了Behaviors的概念:

Behaviors非常类似于ASP.NET Core中的MiddleWare,可以让我们实现管道模式。

管道实现

要定义Behaviors,我们需要实现IPipelineBehavior接口,示例代码如下:

public class FirstPipelineBehavior<TRequest, TResponse>: IPipelineBehavior<TRequest, TResponse>
{public async Task<TResponse> Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate<TResponse> next){Console.WriteLine("FirstPipelineBehavior执行中");var response = await next();Console.WriteLine("FirstPipelineBehavior执行完成");return response;}
}

和MiddleWare类似,调用next()可以将请求向下传递。

接着在Startup.cs中注册管道:

services.AddMediatR(typeof(Startup));
services.AddTransient(typeof(IPipelineBehavior<,>), typeof(FirstPipelineBehavior<,>));
services.AddTransient(typeof(IPipelineBehavior<,>), typeof(SecondPipelineBehavior<,>));
services.AddTransient(typeof(IPipelineBehavior<,>), typeof(ThirdPipelineBehavior<,>));

访问API可以看到,管道可以在IRequestHandler执行之前和之后执行代码,并且处理顺序和注册顺序相同

结论

通过本文,我们了解到,通过MediatR提供的Behaviors功能,不依赖ASP.NET Core框架,可以在业务层实现管道模式。

如果你觉得这篇文章对你有所启发,请关注我的个人公众号”My IO“,记住我!

为什么应该在业务层实现管道模式,而不用ASP.NET Core Middleware实现 | 2点原因和实现方式...相关推荐

  1. 在业务层实现校验请求参数

    前言 在前面的文章中,我们介绍了在业务层实现管道模式: 响应缓存 记录请求日志 今天,我们同样使用IPipelineBehavior,介绍如何在业务层实现校验请求参数,用于检查输入是否满足业务要求. ...

  2. 如何在业务层实现响应缓存

    前言 上次,我们介绍了应该在业务层实现管道模式 响应缓存是ASP.NET Core中很重要的功能,它可以存储响应,并提供来自缓存的响应,以便提高程序性能. 响应缓存通常是通过Middleware实现的 ...

  3. 检测到在集成的托管管道模式下不适用的 ASP.NET 设置, HTTP 错误 500.23 解决方案...

    由于32位和64位操作系统存在着比较大的区别, 对于在32位操作系统开发出来的网站程序或者其他软件在64位操作系统上就有可能出现问题, 例如, 最近在配置一个网站程序到server 2008 R2系统 ...

  4. ASP.NET Core 中的管道机制

    首先,很感谢在上篇文章 C# 管道式编程 中给我有小额捐助和点赞的朋友们,感谢你们的支持与肯定.希望我的每一次分享都能让彼此获得一些收获,当然如果我有些地方叙述的不正确或不当,还请不客气的指出.好了, ...

  5. J2EE业务层模式:服务门面,应用服务,以及业务委托,服务定位器

    现在J2EE领域无论是表现层,业务层还是持久层,框架满天飞,虽然说框架为我们省了很大的力气,但是我们还是需要掌握J2EE里面经常用到的一些模式,下面对J2EE领域业务层的几个模式做一个小的总结: 服务 ...

  6. 走向.NET架构设计—第五章—业务层模式,原则,实践(中篇)

    走向.NET架构设计-第五章-业务层模式,原则,实践(中篇) 前言:设计模式并不是什么很高深的东西,至少不是那么"神乎其神".说到底,设计模式就是一些设计思想.下面我们就走进项目, ...

  7. 走向.NET架构设计—第五章—业务层模式,原则,实践(后篇)

    走向.NET架构设计-第五章-业务层模式,原则,实践(后篇) 前言:在上一篇文章中,讲述了一些设计模式的使用,本篇首先接着介绍还没有讲完的一些设计模式,然后再讲述一些架构模式中的超类模式,作为本篇的结 ...

  8. 设计模式-责任链模式变体之管道模式

    一.管道模式的定义   管道模式(Pipeline Pattern) 是责任链模式(Chain of Responsibility Pattern)的常用变体之一.在管道模式中,管道扮演着流水线的角色 ...

  9. 走向.NET架构设计—第四章—业务层分层架构(后篇)

    走向.NET架构设计-第四章-业务层分层架构(后篇) 前言: 在上一篇文章中,我们讨论了组织业务逻辑的模式:Transaction Script和Active Record,Domain Model. ...

最新文章

  1. 怎么提高单片机编程水平?
  2. h5自定义相机界面_MIUI 12全新相机发布,多款相机图标进行重绘,可升级机型一览...
  3. js中JSON.stringify用于自定义的类
  4. c语言打印一个整数的二进制形式
  5. 初识openstack
  6. 参与社团活动的意义_大学参加社团活动有意义吗?
  7. python多重继承super父类参数_python – 多重继承如何与super()和不同的__init __()参数一起使用?...
  8. Python核心编程读笔 4
  9. c++学习---继承与派生类
  10. socketpair机制
  11. cad帧数测试软件,怎样让cad运行速度更快_cad如何设置运行更流畅
  12. ttest求pvalue_TTEST 在EXCEL计算出的结果是t还是p值
  13. 如何才能找到影音文件的真实下载地址
  14. 悲伤的时候总会想起什么
  15. 2018年机器学习从业者_机器学习从业者在2020年及以后创造收入的5种方式
  16. 光学系统像差的计算机模拟,XCCHJJ-B 光学系统像差传函焦距测量综合实验装置
  17. 亲历被盗iPhone流通链:串号泄露机主信息
  18. 个人博客开源系统XBlog介绍和部署
  19. nvm介绍、nvm下载、安装与使用
  20. python笛卡尔心脏线绘制_python 笛卡尔

热门文章

  1. windows2003——IIS
  2. MessagePack Java 0.6.X List, Map 对象的序列化和反序列化
  3. 常用数据库连接和diriver以及默认端口
  4. P3174 [HAOI2009]毛毛虫(树形dp)
  5. 【几何/分治】【最短路】【数学期望】Day 10.24
  6. iOS runtime实战应用:关联对象
  7. LeetCode: 14. Longest Common Prefix
  8. Cnblogs自定义皮肤css样式-星空观测者
  9. 管理员获得所有权_在Windows 7中获得注册表项的所有权
  10. [置顶] C#中通过调用webService获取上网IP地址的区域的方法