예제 #1
0
 private bool Equals(EntityAndEvent other)
 {
     //Only equal if class has the RemoveDuplicate attribute
     return(HasRemoveDuplicateAttribute &&
            EntityEvent.GetType() == other.EntityEvent.GetType() &&
            ReferenceEquals(CallingEntity, other.CallingEntity));
 }
        /// <summary>
        /// This finds either sync or async handlers for the event and runs the handlers with the input event
        /// </summary>
        /// <param name="entityAndEvent"></param>
        /// <param name="loopCount">This gives the loop number for the RunBefore/AfterSaveChangesEvents</param>
        /// <param name="beforeDuringOrAfter">tells you what type of event to find/Run</param>
        /// <param name="allowAsync">true if async is allowed</param>
        /// <returns>Returns a Task containing the combined status from all the event handlers that ran</returns>
        public async ValueTask <IStatusGeneric> RunHandlersForEventAsync(EntityAndEvent entityAndEvent, int loopCount,
                                                                         BeforeDuringOrAfter beforeDuringOrAfter, bool allowAsync)
        {
            var status = new StatusGenericHandler
            {
                Message = "Successfully saved."
            };

            var handlersAndWrappers = _findHandlers.GetHandlers(entityAndEvent, beforeDuringOrAfter, allowAsync);

            foreach (var handlerWrapper in handlersAndWrappers)
            {
                LogEventHandlerRun(loopCount, beforeDuringOrAfter, handlerWrapper);
                if (beforeDuringOrAfter == BeforeDuringOrAfter.BeforeSave)
                {
                    var handlerStatus = handlerWrapper.IsAsync
                        ? await((BeforeSaveEventHandlerAsync)Activator.CreateInstance(handlerWrapper.WrapperType, handlerWrapper.EventHandler))
                                        .HandleAsync(entityAndEvent.CallingEntity, entityAndEvent.EntityEvent).ConfigureAwait(false)
                        : ((BeforeSaveEventHandler)Activator.CreateInstance(handlerWrapper.WrapperType, handlerWrapper.EventHandler))
                                        .Handle(entityAndEvent.CallingEntity, entityAndEvent.EntityEvent);
                    if (handlerStatus != null)
                    {
                        status.CombineStatuses(handlerStatus);
                    }
                }
                else if (beforeDuringOrAfter == BeforeDuringOrAfter.AfterSave)
                {
                    if (handlerWrapper.IsAsync)
                    {
                        await((AfterSaveEventHandlerAsync)Activator.CreateInstance(handlerWrapper.WrapperType,
                                                                                   handlerWrapper.EventHandler))
                        .HandleAsync(entityAndEvent.CallingEntity, entityAndEvent.EntityEvent).ConfigureAwait(false);
                    }
                    else
                    {
                        ((AfterSaveEventHandler)Activator.CreateInstance(handlerWrapper.WrapperType,
                                                                         handlerWrapper.EventHandler))
                        .Handle(entityAndEvent.CallingEntity, entityAndEvent.EntityEvent);
                    }
                }
                else
                {
                    //Its either of the during events

                    var handlerStatus = handlerWrapper.IsAsync
                        ? await((DuringSaveEventHandlerAsync)Activator.CreateInstance(handlerWrapper.WrapperType, handlerWrapper.EventHandler))
                                        .HandleAsync(entityAndEvent.CallingEntity, entityAndEvent.EntityEvent, _uniqueValue)
                                        .ConfigureAwait(false)
                        : ((DuringSaveEventHandler)Activator.CreateInstance(handlerWrapper.WrapperType, handlerWrapper.EventHandler))
                                        .Handle(entityAndEvent.CallingEntity, entityAndEvent.EntityEvent, _uniqueValue);
                    if (handlerStatus != null)
                    {
                        status.CombineStatuses(handlerStatus);
                    }
                }
            }

            return(status);
        }
예제 #3
0
        /// <summary>
        /// This finds the handlers for the event and runs the handlers with the input event
        /// </summary>
        /// <param name="entityAndEvent"></param>
        /// <param name="loopCount">This gives the loop number for the RunBefore/AfterSaveChangesEvents</param>
        /// <param name="beforeSave">true for BeforeSave, and false for AfterSave</param>
        /// <returns>Returns status with </returns>
        public IStatusGeneric RunHandlersForEvent(EntityAndEvent entityAndEvent, int loopCount, bool beforeSave)
        {
            var status = new StatusGenericHandler
            {
                Message = "Successfully saved."
            };

            var eventType        = entityAndEvent.DomainEvent.GetType();
            var handlerInterface = (beforeSave ? typeof(IBeforeSaveEventHandler <>) : typeof(IAfterSaveEventHandler <>))
                                   .MakeGenericType(eventType);
            var wrapperType = (beforeSave ? typeof(BeforeSaveHandler <>) : typeof(AfterSaveHandler <>))
                              .MakeGenericType(eventType);
            var handlers = _serviceProvider.GetServices(handlerInterface).ToList();

            var beforeAfter = beforeSave ? "BeforeSave" : "AfterSave";

            if (!handlers.Any())
            {
                _logger.LogError($"Missing handler for event of type {eventType.FullName} for {beforeAfter} event handler.");
                throw new GenericEventRunnerException(
                          $"Could not find a {beforeAfter} event handler for the event {eventType.Name}.",
                          entityAndEvent.CallingEntity, entityAndEvent.DomainEvent);
            }

            foreach (var handler in handlers)
            {
                _logger.LogInformation($"{beforeAfter[0]}{loopCount}: About to run a {beforeAfter} event handler {handler.GetType().FullName}.");
                if (beforeSave)
                {
                    var wrappedHandler = (BeforeSaveEventHandler)Activator.CreateInstance(wrapperType, handler);
                    var handlerStatus  = wrappedHandler.Handle(entityAndEvent.CallingEntity, entityAndEvent.DomainEvent);
                    if (handlerStatus != null)
                    {
                        status.CombineStatuses(handlerStatus);
                    }
                }
                else
                {
                    var wrappedHandler = (AfterSaveEventHandler)Activator.CreateInstance(wrapperType, handler);
                    wrappedHandler.Handle(entityAndEvent.CallingEntity, entityAndEvent.DomainEvent);
                }
            }

            return(status);
        }
        public List <HandlerAndWrapper> GetHandlers(EntityAndEvent entityAndEvent, BeforeDuringOrAfter beforeDuringOrAfter, bool lookForAsyncHandlers)
        {
            var eventType     = entityAndEvent.EntityEvent.GetType();
            var asyncHandlers = new List <object>();

            List <object> GetAsyncHandlers()
            {
                var asyncHandlerInterface = GetEventHandlerGenericType(beforeDuringOrAfter, true)
                                            .MakeGenericType(eventType);

                asyncHandlers = _serviceProvider.GetServices(asyncHandlerInterface).ToList();
                return(asyncHandlers);
            }

            if (lookForAsyncHandlers)
            {
                asyncHandlers = GetAsyncHandlers();
            }
            var syncHandlerInterface = GetEventHandlerGenericType(beforeDuringOrAfter, false)
                                       .MakeGenericType(eventType);

            var syncHandler = _serviceProvider.GetServices(syncHandlerInterface)
                              //This removes sync event handlers that have the same name
                              .Where(x => asyncHandlers.All(y =>
                                                            !string.Equals(x.GetType().Name + "Async", y.GetType().Name, StringComparison.InvariantCultureIgnoreCase)))
                              .ToList();

            var result = asyncHandlers.Select(x => new HandlerAndWrapper(x, eventType, beforeDuringOrAfter, true))
                         .Union(syncHandler.Select(x => new HandlerAndWrapper(x, eventType, beforeDuringOrAfter, false))).ToList();

            if (!result.Any())
            {
                var suffix = GetAsyncHandlers().Any() ? " Their was a suitable async event handler available, but you didn't call SaveChangesAsync." : "";
                _logger.LogError($"Missing handler for event of type {eventType.FullName} for {beforeDuringOrAfter} event handler.{suffix}");
                throw new GenericEventRunnerException(
                          $"Could not find a {beforeDuringOrAfter} event handler for the event {eventType.Name}.{suffix}",
                          entityAndEvent.CallingEntity, entityAndEvent.EntityEvent);
            }

            return(result);
        }