/// <summary> /// Main entry point of the dispatcher. Dispatches the given message, doing handler /// lookup etc. Any exceptions thrown will bubble up. /// </summary> public void Dispatch <TMessage>(TMessage message) { IHandleMessages[] handlersToRelease = null; try { var typesToDispatch = GetTypesToDispatch(typeof(TMessage)); var handlersFromActivator = typesToDispatch.SelectMany(GetHandlerInstances); var handlerInstances = handlersFromActivator.ToArray(); // add own internal handlers var handlerPipeline = handlerInstances.Concat(OwnHandlersFor <TMessage>()).ToList(); // allow pipeline to be filtered var handlersToExecute = inspectHandlerPipeline.Filter(message, handlerPipeline).ToArray(); // keep track of all handlers pulled from the activator as well as any handlers // that may have been added from the handler filter handlersToRelease = handlerInstances.Union(handlersToExecute).ToArray(); var distinctHandlersToExecute = handlersToExecute.Distinct().ToArray(); if (!distinctHandlersToExecute.Any()) { log.Warn("The dispatcher could not find any handlers to execute with message of type {0}", typeof(TMessage)); } else { foreach (var handler in distinctHandlersToExecute) { log.Debug("Dispatching {0} to {1}", message, handler); var handlerType = handler.GetType(); foreach (var typeToDispatch in GetTypesToDispatchToThisHandler(typesToDispatch, handlerType)) { GetDispatcherMethod(typeToDispatch).Invoke(this, new object[] { message, handler }); if (MessageContext.MessageDispatchAborted) { break; } } if (MessageContext.MessageDispatchAborted) { break; } } } } finally { if (handlersToRelease != null) { try { activateHandlers.Release(handlersToRelease); } catch (Exception e) { log.Error(e, "An error occurred while attempting to release handlers: {0}", string.Join(", ", handlersToRelease.Select(h => h.GetType()))); } } } }
public void Release(IEnumerable handlerInstances) { handlerActivator.Release(handlerInstances); }
/// <summary> /// Main entry point of the dispatcher. Dispatches the given message, doing handler /// lookup etc. Any exceptions thrown will bubble up. /// </summary> public async Task Dispatch <TMessage>(TMessage message) { IHandleMessages[] handlersToRelease = null; try { var typesToDispatch = GetTypesToDispatch(typeof(TMessage)); var handlersFromActivator = typesToDispatch.SelectMany(GetHandlerInstances); var handlerInstances = handlersFromActivator.ToArray(); // add own internal handlers var handlerPipeline = handlerInstances.Concat(OwnHandlersFor <TMessage>()).ToList(); // allow pipeline to be filtered var handlersToExecute = inspectHandlerPipeline.Filter(message, handlerPipeline).ToArray(); // keep track of all handlers pulled from the activator as well as any handlers // that may have been added from the handler filter handlersToRelease = handlerInstances.Union(handlersToExecute).ToArray(); var distinctHandlersToExecute = handlersToExecute.Distinct().ToArray(); if (!distinctHandlersToExecute.Any()) { throw new UnhandledMessageException(message); } if (!(storeSagaData is ICanUpdateMultipleSagaDatasAtomically)) { CheckMultipleSagaHandlers(message, distinctHandlersToExecute); } foreach (var handler in distinctHandlersToExecute) { log.Debug("Dispatching {0} to {1}", message, handler); var handlerType = handler.GetType(); foreach (var typeToDispatch in GetTypesToDispatchToThisHandler(typesToDispatch, handlerType)) { try { await(Task) GetDispatcherMethod(typeToDispatch) .Invoke(this, new object[] { message, handler }); } catch (TargetInvocationException tie) { var exception = tie.InnerException; exception.PreserveStackTrace(); throw exception; } if (MessageContext.MessageDispatchAborted) { break; } } if (MessageContext.MessageDispatchAborted) { break; } } } finally { if (handlersToRelease != null) { try { activateHandlers.Release(handlersToRelease); } catch (Exception e) { log.Error(e, "An error occurred while attempting to release handlers: {0}", string.Join(", ", handlersToRelease.Select(h => h.GetType()))); } } } }