前言
上次,我们介绍了使用MediatR的Behaviors功能,在业务层实现管道模式。(《为什么应该在业务层实现管道模式,而不用ASP.NET Core Middleware实现 | 2点原因和实现方式》)
但是,这种管道有个特点或者说缺点,不管你需不需要,所有请求都要经过管道处理,而且处理顺序必须一致。
下面,我们介绍一种更轻量的实现方式。
Brighter
Brighter
一个命令处理器和调度程序实现,支持任务队列的轻量级类库。
它的使用方式和MediatR
类似,同样可以实现业务逻辑和Controller进行隔离。
1.引用nuget包
创建Web API项目,并引用nuget包Paramore.Brighter.AspNetCore
。
2.定义请求数据
添加一个新类DemoCommand
,实现IRequest
接口:
public class DemoCommand : IRequest
{public Guid Id { get; set; }public string Name { get; set; }
}
3.实现请求处理程序
添加一个新类DemoCommandHandler
,继承基类RequestHandler<TRequest>
,TRequest
对应实现了IRequest
接口的类:
public class DemoCommandHandler : RequestHandler<DemoCommand>
{public override DemoCommand Handle(DemoCommand command){Console.WriteLine("DemoQueryHandler执行");return base.Handle(command);}
}
4.实现API
Controller没有任何业务逻辑,仅将请求通过commandProcessor发送:
private readonly IAmACommandProcessor _commandProcessor;
public WeatherForecastController(IAmACommandProcessor commandProcessor)
{_commandProcessor = commandProcessor;
}[HttpPost]
public void Demo(DemoCommand command)
{_commandProcessor.Send(command);
}
5.添加Brighter配置
打开Startup.cs,在ConfigureServices
方法中,添加如下代码:
services.AddBrighter().HandlersFromAssemblies(typeof(Startup).Assembly);
6.运行
运行程序,访问API地址,可以看到输出正常,说明请求已通过Brighter发送给请求处理程序处理。
实现独立管道
Brighter提供了一种被称为俄罗斯套娃
的模型,可以将多个RequestHandler
串联起来执行同一个请求,比如为DemoCommandHandler加上LogHandler(写日志)和ValidateHandler(检查请求参数合法性)。
这就相当于为每个请求处理程序提供了一条独立管道。
要实现俄罗斯套娃
,我们必须创建一个Attribute来继承RequestLoggingAttribute
:
public class FirstPipelineAttribute: RequestHandlerAttribute
{public FirstPipelineAttribute(int step, HandlerTiming timing): base(step, timing){ }public override Type GetHandlerType(){return typeof(FirstPipelineHandler<>);}
}public class FirstPipelineHandler<TRequest> : RequestHandler<TRequest> where TRequest: class, IRequest
{public override TRequest Handle(TRequest request){Console.WriteLine("FirstPipelineHandler执行");return base.Handle(request);}
}
step 定义在管道中的执行顺序
timing 在请求处理程序之前还是之后执行
GetHandlerType() 返回具体处理方法的实现,同样要继承自
RequestHandler<TRequest>
然后在具体的Handle
声明这些Attribute:
[FirstPipeline(1, HandlerTiming.Before)]
[SecondPipeline(2, HandlerTiming.Before, typeof(SecondPipelineHandler<>))]
[SecondPipeline(3, HandlerTiming.After, typeof(ThirdPipelineHandler<>))]
public override DemoCommand Handle(DemoCommand command)
可以看到,管道的处理顺序和step、timing的设置相同:
结论
通过本文,我们可以了解到,Brighter
可以为每个请求实现独立的管道,这样可以更灵活地控制管道执行的内容和顺序。
想了解更多内容,请关注我的个人公众号”My IO“