Example #1
0
        /// <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())));
                    }
                }
            }
        }
Example #2
0
        /// <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())));
                    }
                }
            }
        }