手机版

如何利用Asp.Net核心的中间件思想处理复杂的业务流程

时间:2021-08-30 来源:互联网 编辑:宝哥软件园 浏览:

前言

最近利用Asp.Net Core的MiddleWare思想重构了公司的旧代码,在这里分享了我的设计思路,希望能帮助大家处理复杂的流程业务。

背景

一个流程初始化接口,需要根据传入的流程类型做一些不同的工作。

1.有些工作无论流程类型如何都要完成(总计),有些工作对于某个流程是唯一的。

2.处理任务之间基本不存在嵌套关系,所以代码基本都是运行账号的。

3.进程有很多种,if或switch判断在代码中占据了很大的空间。

4.这些加工工作大致可以分为三类,包括前期准备工作(参数标定等)。),处理工作(更新数据库、插入数据等)。),以及收尾工作(记录、通知等)。)

Asp.Net核心中间件

注意第二项,流水账的代码,让我想起了《管道模型》,Asp.Net Core的中间件就放在这个管道里。

请看下图:

中间件有三个:中间件1、中间件2、中间件3,放在一个中间件集合(PipeLine)中,排列有序。请求请求1从2流向3,结果响应相应地从底层流出。

请求和解决方案被封装在我们经常看到的上下文中。上下文被传递到中间件1,然后在被中间件1处理之后,上下文被传递到中间件2,直到它到达最后一个。

我们在配置启动时经常调用的app.use()方法实际上是添加一个中间件,Context集合。上下文进入后,必须由这个中间件处理。

我不知道我说了什么,但是你有管道模型处理任务的这个概念吗?

代码解释

不明白?没关系,我们来看看代码。

如上所述,每个中间件将通过自己的主体传递上下文,并主动调用下一个中间件。

那么,什么是中间件呢?传入的是Context,传出的是Context,这是一种方法吗?不要。

是传入委托和传出委托,此传入委托和传出委托的参数是上下文,如下所示:

///Summary////管道中的委托任务////Summary//param name=' context '/param////返回/返回tcontext (tcontext context)中的公共委托任务管道委托;因此,中间件是下面的Func,它肩负着调用下一个中间件(委托)的重任:

Funcpipelinedelegatecontext、pipelinedelegatecontext和什么是管道?是Func的集合,如下所示:

IListFuncPipeLineDelegateTContext,PipeLineDelegateTContext _ components=new listfiplinedelegatetcontext,PipeLineDelegateTContext();我们在启动方法中使用配置方法做什么?实际上,它正在向上述pipeline _components添加一个函数,如下所示:

public ipipipelinebuilddertcontext Use(Funcpipelinedelegatetcontext,Pipelinedelegatetcontext func){ _ components。add(func);归还这个;}但是在今天的使用中,我也想重载一下原来的使用,如下:

public ipipipelinebuilddertcontext Use(ActionTContext action,int?索引=null){ Funcpipelinedelegatetcontext,Pipelinedelegatetcontext PipleDelegate=next={返回上下文={ action .调用(上下文);下一个返回调用(上下文);};};如果(索引. HasValue)如果(索引值_组件计数)引发新的异常('插入索引超出目前管道大小');else { _components .插入(索引。值,PipleDelegate);} else { _components .add(next={ return context={ action .调用(上下文);下一个返回调用(上下文);};});}退回这个;}可以看到,重载之后,传入的变成了ActionTContext操作,因为我想外部专注于自己要真正处理的业务,而调用下一个中间件的事情封装到方法内部,不用外部来关心了,并且,可以通过传入的指数指定插入的中间件的位置,以此来控制业务的执行顺序。

最后,需要把传入的委托链接起来,这就是管道的建设工作,代码如下:

public PipeLineDelegateTContext Build(){ var request delegate=(PipeLineDelegateTContext)(上下文=Task .已完成的任务);foreach (var func in _components .reverse())请求委托=func(请求委托);返回requestDelegate}到这里,管道相关的差不多说完了,那我,我如何利用上面的思想来处理我的业务呢?

处理业务

处理示意图

步骤:

初始化三条处理管道(根本是新的三个列表任务集合,对应前期准备工作集合,处理中工作的集合,扫尾工作的集合)。

向三条管道中注入公共的处理任务。

根据传入的流程类型动态加载对应的处理方法手柄().

手柄方法向三条管道中注入该类型的流程所对应的特有任务。

构建三条管道。

依此执行准备工作管道=处理中管道=处理后管道。

上面步骤可以概括成下面的代码。

private void InitApproveFlow(approveflow initcontext){ var beforepipeline builder=initbeforepline();var handlingpipeline builder=InitHandlingPipeLine();var after pipeline builder=initafter pipeline();registerentitypeline(上下文。流类型,beforePipeLineBuilder,handlingPipeLineBuilder,after pipeline builder);管道之前的var管道构建器之前.build();var handling Pipeline=handling Pipeline Builder .build();管道后的var管道构建器后的var .build();管道之前.调用(上下文);手动管道.调用(上下文);后管道调用(上下文);}其中,RegisterEntityPipLine()方法根据flowType动态加载对应的类,所有类继承了一个公共的接口,接口暴露出了处理方法。

private void registerentitypeline(字符串flowType,ipippelinebuilder在管道构建器之前proveflowing context,ippelinebuilder在管道构建器之后proveflowing context,ippelinebuilder在管道构建器之后proveflowing context){ var handleclass name=('类名的前缀flowType ).toLower();定义变量类型=AppDomain .CurrentDomain。GetAssemblies().其中(a=a。全名。包含('程序及名称')) .选择许多(a=a.GetTypes().其中(t=t . GetInterfaces().包含(类型为(类继承的接口名称)) ) ).FirstOrDefault(u=u.FullName!=null u . name。to lower()==handleClassName);if (type==null)引发新的ObjectNotFoundException(“”未找到名称为[' handleClassName ']的类');定义变量句柄=(类继承的接口名称)_serviceProvider .GetService(类型);把手。句柄(在管道构建器之前、管道构建器之后);}手柄方法里面又做了什么呢?

public void Handle(ipipipelinebuilderproveflowinitcontext before pipeline builder,ipipipelinebuilderproveflowinitcontext handling pipeline builder,ipipipelinebuilderproveflowinitcontext after pipeline builder){ HandleBefore(before pipeline builder);搬运(handlingpipeline builder);HandleAfter(afterpipeline builder);}在三个管道之前、期间和之后添加相应的任务。

质量保证

Q1:如果处理任务取决于前一个处理任务的处理结果会怎样?

PipeLineDelegateTContext中的TContext是一个对象,可以向其中添加相应的属性。上游任务处理任务并为上下文中的属性赋值,供下游任务使用。

Q2:如果一个任务需要在其他任务之前执行,该怎么办?

在管道构建器中。使用(),有一个索引参数,通过它可以指定插入任务的位置。

Q3:如果管道的通用性有保证(不限于某项服务)?

TContext是通用的,可以针对不同的任务创建相应的TContext,实现不同服务下的PipleLine复用。

摘要

以上就是本文的全部内容。希望本文的内容对大家的学习或工作有一定的参考价值。有问题可以留言交流。谢谢你的支持。

版权声明:如何利用Asp.Net核心的中间件思想处理复杂的业务流程是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。