0

I'm looking for a solution to use INotification in MediatR, what I'm trying to do is handling the commits and changes in INotificationHandler, instead of IRequestHandler.

Does it make sense to do so? Product-> AddProduct->ProductWasAdded.

 public class AddProductCommandHandler : IRequestHandler<AddProductCommand, Result<ProductTypeId>>
    {
      private readonly DbContext _writeContext;
      private readonly IMediator               _mediator;

      public AddProductCommandHandler( DbContext writeContext, IMediator mediator )
      {
        _writeContext  = writeContext;
        _mediator = mediator;
      }

      public async Task<Result<ProductTypeId>> Handle( AddProductCommand request, CancellationToken cancellationToken )
      {
           //Logics ommitedfor bravety
           await _mediator.Publish( new ProductWasAddedEvent(product), cancellationToken );
      }
    }

and in INotificationHandler:

  public class ProductWasAddedEvent:INotification
  {
    public Product Product     { get; }
    public ProductWasAddedEvent(Product product)
    {
      Product= product;
    }
  }

Finally in INotificationHandler:

public class ProductEvents:INotificationHandler<ProductWasAddedEvent>
  {
    private readonly DbContext _writeContext;

    public ProductEvents( DbContext writeContext )
    {
      _writeContext = writeContext;
    }

    public async Task Handle( ProductWasAddedEvent notification, CancellationToken cancellationToken )
    {
      await _writeContext.Products.AddAsync( notification.Product, cancellationToken );
      await _writeContext.SaveChangesAsync( cancellationToken );
    }
  }
Ocelot
  • 203
  • 3
  • 11
  • What is supposed to be in your RequestHandler, if you are moving the logic? – Loxx Apr 11 '22 at 11:48
  • checking the validation of entity and etc will remain in RequestHandler. like : var result=Product.Create( request.Name ); if result is succeeded then I will call _mediator.Publish. there could be several validations in requestHandler logics. – Ocelot Apr 11 '22 at 12:07
  • In my opinion it does not makes sense to move "database" logic to a notification. Is there a reason you want to split it out? See https://stackoverflow.com/a/63186929/10561636 for a good request/notifcation explanation – Loxx Apr 11 '22 at 12:20
  • Thanks for the link, I suppose to use event instead of command. I want to follow DDD domain events and instead of using commands I want to use events. – Ocelot Apr 11 '22 at 13:29

1 Answers1

0

I guess it highly depends on whether you're handling the "events" in separate microservices or perhaps if you plan on sending them through a real message bus (eg. RabbitMQ, Kafka).

If you're handling everything in memory in a single process, you might be good with your current approach. However, resiliency and fault tolerance are not exactly guaranteed. For that you might want to look at the Outbox pattern. It would let you to create a single transaction on your DB, persist your data AND the messages/events you want to dispatch. Then a separate background service will take care of sending them.

David Guida
  • 950
  • 9
  • 19