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); }
/// <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); }