We have more than 15 event handlers corresponding to each event type. I want to avoid below switch case in Event Dispatcher to call corresponding event handler based on the event type.
Here is my Event Dispatcher class:
public class EventDispatcher : IEventDispatcher
{
private readonly IServiceProvider _serviceProvider;
public EventDispatcher(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
public async Task<ResultDto> HandleEvent(IEvent @event, ILogger logger)
{
ResultDto resultDto = null;
switch (@event.EventType)
{
case EventType.CARD_BLOCK:
resultDto = await HandleAsync<CardBlockedEvent>(@event as CardBlockedEvent, logger);
break;
case EventType.CARD_UNBLOCK:
resultDto = await HandleAsync<CardUnBlockedEvent>(@event as CardUnBlockedEvent, logger);
break;
case EventType.CARD_CANCEL:
resultDto = await HandleAsync<CardCancelledEvent>(@event as CardCancelledEvent, logger);
break;
case EventType.CARD_GROUP_CHANGED:
resultDto = await HandleAsync<CardGroupChangedEvent>(@event as CardGroupChangedEvent, logger);
break;
case EventType.CARD_EXPIRY:
resultDto = await HandleAsync<CardExpiredEvent>(@event as CardExpiredEvent, logger);
break;
default:
logger.Warning($"Unknown event type");
resultDto = new ResultDto { ResultType = ResultType.Failure, Message = "Unknown event type" };
break;
}
return resultDto;
}
private async Task<ResultDto> HandleAsync<TEvent>(TEvent @event, ILogger logger) where TEvent : IEvent
{
var handler = _serviceProvider.GetService(typeof(IEventHandler<ResultDto, TEvent>)) as IEventHandler<ResultDto, TEvent>;
return await handler.HandleAsync(@event, logger);
}
}
Below is the Dependency Registrations:
public class EventHandlerIoCRegistrations : IRegisterSevices
{
public void RegisterServicesWith(IServiceCollection serviceCollection)
{
RegisterDispatcher(serviceCollection);
RegisterHandlers(serviceCollection);
}
private void RegisterDispatcher(IServiceCollection serviceCollection)
{
serviceCollection.AddTransient<IEventDispatcher, EventDispatcher>();
}
private void RegisterHandlers(IServiceCollection serviceCollection)
{
Assembly.GetExecutingAssembly()
.GetTypes()
.Where(item => item.GetInterfaces()
.Where(i => i.IsGenericType).Any(i => i.GetGenericTypeDefinition() == typeof(IEventHandler<,>)) && !item.IsAbstract && !item.IsInterface)
.ToList()
.ForEach(assignedTypes =>
{
var serviceType = assignedTypes.GetInterfaces().First(i => i.GetGenericTypeDefinition() == typeof(IEventHandler<,>));
serviceCollection.AddScoped(serviceType, assignedTypes);
});
}
}
Below is the Event handler interface:
public interface IEventHandler<TResult, TEvent>
where TEvent : IEvent
where TResult : class
{
/// <summary>
///
/// </summary>
/// <param name="event"></param>
/// <param name="logger"></param>
/// <returns></returns>
Task<TResult> HandleAsync(TEvent @event, ILogger logger);
}
Is there any better way to do and to avoid this switch case? Any thoughts?
Aucun commentaire:
Enregistrer un commentaire