public static IServiceCollection AddMemoryEventBus(this IServiceCollection services, Assembly[] handlerAssemblies)
        {
            services.TryAddSingleton <MemoryEventBusStarter>();
            services.TryAddSingleton <IEventPublish, MemoryEventPublish>();

            ConcurrentDictionary <string, Type> eventHandlerMap = new ConcurrentDictionary <string, Type>();

            foreach (var handlerType in handlerAssemblies.SelectMany(assembly => assembly.GetTypes().Where(type => type.IsClass && typeof(IEventHandler).IsAssignableFrom(type))))
            {
                EventHandlerAttribute eventHandlerAttribute = handlerType.GetCustomAttribute <EventHandlerAttribute>();
                if (eventHandlerAttribute == null)
                {
                    throw new InvalidOperationException($"The type {handlerType.FullName} should have {nameof(EventHandlerAttribute)} attribute");
                }

                if (!eventHandlerMap.TryAdd(eventHandlerAttribute.ThrowIfNull(nameof(eventHandlerAttribute)).EventName, handlerType))
                {
                    throw new InvalidOperationException($"There are duplicate handlers for one event name {eventHandlerAttribute.EventName}");
                }

                services.Add(new ServiceDescriptor(handlerType, handlerType, eventHandlerAttribute.HandlerLifetime));
            }

            services.AddSingleton(sp => new MemoryEventDispatcher(sp, sp.GetRequiredService <ILogger <MemoryEventDispatcher> >(), eventHandlerMap));

            return(services);
        }