elsa这个框架运用管道来实现切面编程,切面编程的意义我的理解是在于:把业务逻辑和其他与业务不相关的逻辑进行解耦,或者把通用的逻辑:异常处理,日志处理等在不侵入业务逻辑的情况下,服务与这些业务。接下来,详细看看elsa框架的管道是怎么实现的。
主要依靠,下面这个委托方法,这个方法返回一个ValueTask对象,传入一个流程执行上下文参数。
注意:elsa一共有两种管道一个是workFlow的,一个是activity的,参数不一样,返回值一样,但他们各自管道内部的原理是一样的,这里以Activity管道举例。
依靠这个委托类型,elsa所有的不同的切面都会有一个能赋值给这个委托的执行切面入口方法,以便在管道里顺序执行切面。这个切面具体的样子,我举个例子:如异常的切面,代码如图:
它是怎么注册在管道里的呢?看代码:
它是在管道构建器上用了一个扩展方法,UseMiddleware方法,返回一个Func<activitymiddlewaredelgate,activitymiddlewaredelgate>的委托参数,上面提到了IActivityExecutionPipelineBuilder,这个Func就会注册到这个Builder里面。下面看看这个Builder的逻辑:
这个管道构建器有一个_compnents对象,它是用来存放注册的切面的,刚才的切面注册就是Use方法,截图的Build方法就是构建一个切面的调用链:
以上只是管道的注册和构建管道,那么管道在哪运行的呢?
这里注册管道,看看这里的参数ActivityExecutionPiepeline:
它其实就是这个action,这里的pipelie就是Builder,Use这些方法就是在注册切面,而 new ActivityExecutionPipeline(sp ,...Pipeline)对象的内部:
就是Builder.Build,就构建了一个调用链,而这些切面的执行,是靠ExecuteAsync方法实现的。
最终在
这里调用的pipeline
需要注意的是,这里的入口是Workflow的管道,它其实在这个执行过程中,在workflow管道执行结束时,会把workflow上下文转换成activity的上下文,然后在执行activity的管道。
代码如下:
而这个类是在workflow的切面:DefaultActivityScheduler里注册的,至此就能实现从workflow管道到activity管道的转换了。