MediatR Abstract Base Command

I have a scenario, where I would like to Enable/Disable a PurchaseOrderItem

So I have written two separate Command and commandHandlers. Ideally I have to create base abstract class and need to move my logic to one place.

How I can achieve this?

1 answer

  • answered 2021-05-03 19:28 batangaming

    You can do it like this:

    Commands:

    enum CommandType {
      Disable,
      Enable
    }
    
    class EnableCommand : IRequest {
    
    }
    
    class DisableCommand : IRequest {
    
    }
    
    class CommonCommand : IRequest {
      public CommandType Type {get; set;}
    }
    

    Handlers:

    class EnableCommandHandler : IRequestHandler<EnableCommand> {
      private readonly IMediator _mediator;
      public EnableCommandHandler(IMediator mediator) {
        _mediator = mediator;
      }
    
      public async Task Handle(EnableCommand command, CancellationToken cancellationToken) {
        await _mediator.Send(new CommonCommand {Type = CommandType.Enable});
      } 
    }
    
    class DisableCommandHandler : IRequestHandler<DisableCommand> {
      private readonly IMediator _mediator;
      public EnableCommandHandler(IMediator mediator) {
        _mediator = mediator;
      }
    
      public async Task Handle(DisableCommand command, CancellationToken cancellationToken) {
        await _mediator.Send(new CommonCommand {Type = CommandType.Disable});
      } 
    }
    
    class CommonCommandHandler : IRequestHandler<CommonCommand> {
      private readonly IMediator _mediator;
      public EnableCommandHandler(IMediator mediator) {
        _mediator = mediator;
      }
    
      public async Task Handle(CommonCommand command, CancellationToken cancellationToken) {
        ... // some common logic
        switch(command.Type) {
          ... // some specific logic
        }
      } 
    }
    

    And if you don't want to create 3 handlers you can create one for all this commands:

    class CommonCommandHandler : IRequestHandler<EnableCommand> , IRequestHandler<DisableCommand>, IRequestHandler<CommonCommand> {
        public async Task Handle(EnableCommand command, CancellationToken cancellationToken) {
            await Handle(new CommonCommand {Type = CommandType.Enable});
        } 
        public async Task Handle(DisableCommand command, CancellationToken cancellationToken) {
            await Handle(new CommonCommand {Type = CommandType.Disable});
        } 
    
        public async Task Handle(CommonCommand command, CancellationToken cancellationToken) {
            ... // some common logic
            switch(command.Type) {
                ... // some specific logic
            }
        } 
    }
    

    For last options you actually don't need CommonCommand as IRequest. So idea is to re-use handlers.