jasontaylordev / NorthwindTraders

Northwind Traders is a sample application built using ASP.NET Core and Entity Framework Core.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Correct flow for complex operations

inversiondk opened this issue · comments

Hi everybody,
This isn't a technical issue with the code base per se but I thought this might be a good place to ask the question if others are wondering the same.

I'm fairly new to the CQRS / Mediatr setup so please bear with me if I've missed something basic :)
I have a flow where I need to create a customer and afterward a subscription for the customer (which requires a call to an external API). I've set up an IPaymentProvider interface to handle the external API call.

But my question is - what is the correct way of handling this process?
There are a few options

Option A - The classic MVC approach

  1. CustomerController (MVC) calls Mediatr.Send(new CreateCustomerCommand(...);
  2. Upon response, CustomerController (MVC) calls Mediatr.Send(new CreateSubscriptionCommand(...);
  3. The CreateSubscriptionCommandHandler creates the subscription, calls the IPaymentProvider and saves changes to my system

Option B - The Publish event approach

  1. CustomerController (MVC) calls Mediatr.Send(new CreateCustomerCommand(...);
  2. CreateCustomerCommandHandler publishes a notification through Mediatr (CustomerCreated)
  3. The CreateSubscriptionNotificationHandler picks up the notification, creates the subscription, calls the IPaymentProvider and saves changes to my system

Option C - Something else entirely

I hope my question makes sense :)
I'm really REALLY happy with the CQRS/Mediatr set up.... I just need to get it right :)

Thank you guys.

The second option looks good from my point of view. Rather than calling two handlers from the controller, you can publish the notification after creating the customer from CreateCustomerHandler and then create the subscription for that customer on another side!

And also let's say in future if you wanna create a subscription for a specific user then rather than adding if condition in the controller (if we followed the first approach) we can include the same in Create Customer handler to do the same. And having business logic in handler makes more sense than having it in controller level.

But again what I noticed again is that we are doing two things in the same CreateCustomer handler like first creating customers and then publishing notification for the subscription. This is not much complex I mean but still, there is a better way of doing it I think by keeping this logic separate.

Meditr has interface of IRequestPostProcessor which you can wire up with your CreateCustomerCommand like this IRequestPostProcessor<CreateCustomerCommand, ResultType>. Please change the ResultType with your actual result.

public class CreateCustomerPostProcessor :IRequestPostProcessor<CreateCustomerCommand, ResultType>

And the interface has a method called Process which is gets automatically called after handler executes, in that you can publish the notification for creating the subscription for that customer.
In this way, we can separate the logic of Creating Customer and Publishing notification for creating the subscription.

Good point @MCCshreyas - thanks :)
I think I'll explore this path a bit - unless someone feels very strongly about why this should not be the path to take.

Thank you for your interest in this project. This repository has been archived and is no longer actively maintained or supported. We appreciate your understanding. Feel free to explore the codebase and adapt it to your own needs if it serves as a useful reference. If you have any further questions or concerns, please refer to the README for more information.