dimanche 20 septembre 2020

Avoid switch case to call event handler

I want to avoid below switch case to call corresponding event handler based on the event type. We may have more than 20 event types in future.

Here is my code:

public class EventHandlerService : IEventHandlerService
    {
        private readonly IEventHandler<ResultDto, CardBlockedEvent> _cardBlockedEventHandler;
        private readonly IEventHandler<ResultDto, CardUnBlockedEvent> _cardUnblockedEventHandler;
        private readonly IEventHandler<ResultDto, CardCancelledEvent> _cardCancelledEventHandler;
        private readonly IEventHandler<ResultDto, CardGroupChangedEvent> _cardGroupChangedEventHandler;
        private readonly IEventHandler<ResultDto, CardExpiredEvent> _cardExpiredEventHandler;
        public EventHandlerService(
            IEventHandler<ResultDto, CardBlockedEvent> cardBlockedEventHandler,
            IEventHandler<ResultDto, CardUnBlockedEvent> cardUnblockedEventHandler,
            IEventHandler<ResultDto, CardCancelledEvent> cardCancelledEventHandler,
            IEventHandler<ResultDto, CardGroupChangedEvent> cardGroupChangedEventHandler,
            IEventHandler<ResultDto, CardExpiredEvent> cardExpiredEventHandler,
        
            )
        {
            _cardBlockedEventHandler = cardBlockedEventHandler;
            _cardUnblockedEventHandler = cardUnblockedEventHandler;
            _cardCancelledEventHandler = cardCancelledEventHandler;
            _cardGroupChangedEventHandler = cardGroupChangedEventHandler;
            _cardExpiredEventHandler = cardExpiredEventHandler;

            
        }

        public async Task<ResultDto> HandleEvent(IEvent @event, ILogger logger)
        {
            ResultDto resultDto = null;
            switch (@event.EventType)
            {
                case EventType.CARD_BLOCK:
                    resultDto = await _cardBlockedEventHandler.HandleAsync(@event as CardBlockedEvent, logger);
                    break;
                case EventType.CARD_UNBLOCK:
                    resultDto = await _cardUnblockedEventHandler.HandleAsync(@event as CardUnBlockedEvent, logger);
                    break;
                case EventType.CARD_CANCEL:
                    resultDto = await _cardCancelledEventHandler.HandleAsync(@event as CardCancelledEvent, logger);
                    break;
                case EventType.CARD_GROUP_CHANGED:
                    resultDto = await _cardGroupChangedEventHandler.HandleAsync(@event as CardGroupChangedEvent, logger);
                    break;
                case EventType.CARD_EXPIRY:
                    resultDto = await _cardExpiredEventHandler.HandleAsync(@event as CardExpiredEvent, logger);
                    break;
            
                default:
                    logger.Warning($"Unknown event type");
                    resultDto = new ResultDto { ResultType = ResultType.Failure, Message = "Unknown event type" };
                    break;
            }
            return resultDto;
        }

    }

Below is IEventHandler interface:

public interface IEventHandler<TResult, TEvent>
        where TEvent : IEvent
        where TResult : class
    {
        Task<TResult> HandleAsync(TEvent @event, ILogger logger);
    }

Is there a better way to create the right event object without using a big switch statement like above?

Aucun commentaire:

Enregistrer un commentaire