private async Task HandleEvent <TEvent>(TEvent @event, ProjectionHandlerDescriptor descriptor, CancellationToken cancellationToken)
     where TEvent : IEvent
 {
     var genericType   = typeof(IHandleProjectedEvent <>).MakeGenericType(descriptor.EventType);
     var genericMethod = genericType.GetMethod("HandleEvent", BindingFlags.Public);
     var task          = (Task)genericMethod.Invoke(this, new object[] { @event, cancellationToken });
     await task.ConfigureAwait(false);
 }
        private ProjectionHandlerDescriptor GetDescriptorForEvent <TEvent>(TEvent @event)
        {
            var eventType      = @event.GetType();
            var projectionType = GetType();

            Func <Type, ProjectionHandlerDescriptor> valueFactory = (t) =>
            {
                var genericInterface       = typeof(IHandleProjectedEvent <>);
                var genericInterfaceToFind = genericInterface.MakeGenericType(t);
                var hasHandler             = false;

                if (projectionType.GetInterfaces().Any(b => b.Equals(genericInterfaceToFind)))
                {
                    hasHandler = true;
                }

                var descriptorBuilt = new ProjectionHandlerDescriptor(t, hasHandler);
                return(descriptorBuilt);
            };

            var descriptor = descriptorCache.GetOrAdd(eventType, valueFactory);

            return(descriptor);
        }