我们正在使用MediatR为我们的dotnet核心WebAPI后端实现“管道”,以尝试遵循CQRS原则。
我无法决定是否应该尝试实现IPipelineBehavior
链,还是最好构造一个新的Request并从我的Handler方法(针对该请求)中调用MediatR.Send。
实际情况是这样的:
选项1 是我们现在拥有的:DeleteRequest
,由一个类处理,其中,处理程序检查是否正在使用它,将其标记为已删除,然后发送新的TaskStartRequest
,其参数为Delete。
选项2 是我正在考虑的:一个DeleteRequest
,它通过运行以下管道来实现标记接口IRequireCheck
,IStartTask
:>
IPipelineBehavior<IRequireCheck>
首先检查是否正在使用某些东西,IPipelineBehavior<DeleteRequest>
标记某项已在数据库中删除,并且IPipelineBehavior<IStartTask>
以启动任务。我还没有完全弄清楚选项2是什么样子,但这是一般性的想法。
我想我主要是想知道在THandler1的Handler中调用MediatR.Send(TRequest2)是否有代码味道。
答案 0 :(得分:1)
如果这些是您要使用的选项-我说的是选项2。从现有Mediatr处理程序内部发送请求可以视为一种代码味道。您隐藏了副作用并违反了单一责任原则。您还将请求合并在一起,应该避免出现无法先发送一种请求的情况。
但是,我认为可能还有其他选择。如果没有验证和事先标记就无法发生删除请求,则可以为TaskStartRequest
使用预处理器(example here)。这样,您可以拥有一个可以满足您所有需求的单个请求。这甚至可以通过简单地利用现有Mediatr模式来反映您的管道示例。
答案 1 :(得分:0)
是否需要将任务分成多个Handlers
?也许我错过了mediatr
中的要点。这样就够了吗?
public async Task<Result<IFailure,ISuccess>> Handle(DeleteRequest request)
{
var thing = await this.repo.GetById(request.Id);
if (thing.IsBeignUsed())
{
return Failure.BeignUsed();
}
var deleted = await this.repo.Delete(request.Id);
return deleted ? new Success(request.Id) : Failure.DbError();
}