Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Chaining Handlers with MediatR

We are using MediatR to implement a "Pipeline" for our dotnet core WebAPI backend, trying to follow the CQRS principle.

I can't decide if I should try to implement a IPipelineBehavior chain, or if it is better to construct a new Request and call MediatR.Send from within my Handler method (for the request).

The scenario is essentially this:

  • User requests an action to be executed, i.e. Delete something
  • We have to check if that something is being used by someone else
  • We have to mark that something as deleted in the database
  • We have to actually delete the files from the file system.

Option 1 is what we have now: A DeleteRequest which is handled by one class, wherein the Handler checks if it is being used, marks it as deleted, and then sends a new TaskStartRequest with the parameters to Delete.

Option 2 is what I'm considering: A DeleteRequest which implements the marker interfaces IRequireCheck, IStartTask, with a pipeline which runs:

  1. IPipelineBehavior<IRequireCheck> first to check if the something is being used,
  2. IPipelineBehavior<DeleteRequest> to mark the something as deleted in database and
  3. IPipelineBehavior<IStartTask> to start the Task.

I haven't fully figured out what Option 2 would look like, but this is the general idea.

I guess I'm mainly wondering if it is code smell to call MediatR.Send(TRequest2) within a Handler for a TRequest1.

like image 580
gakera Avatar asked Nov 07 '22 13:11

gakera


1 Answers

If those are the options you're set on going with - I say Option 2. Sending requests from inside existing Mediatr handlers can be seen as a code smell. You're hiding side effects and breaking the Single Responsibility Principle. You're also coupling your requests together and you should try to avoid situations where you can't send one type of request before another.

However, I think there might be an alternative. If a delete request can't happen without the validation and marking beforehand you may be able to leverage a preprocessor (example here) for your TaskStartRequest. That way you can have a single request that does everything you need. This even mirrors your pipeline example by simply leveraging the existing Mediatr patterns.

like image 98
Donald McPartland Avatar answered Nov 13 '22 04:11

Donald McPartland