예제 #1
0
        private void InvokeHandler(IServiceBus bus, IMessageHandler handler, TransportMessage transportMessage,
                                   object message, PipelineEvent pipelineEvent, Type messageType)
        {
            var contextType = typeof(HandlerContext <>).MakeGenericType(new[] { messageType });
            var method      = handler.GetType().GetMethod("ProcessMessage", new[] { contextType });

            Guard.Against <ProcessMessageMethodMissingException>(method == null,
                                                                 string.Format(
                                                                     ESBResources.ProcessMessageMethodMissingException,
                                                                     handler.GetType().FullName,
                                                                     transportMessage.MessageType));

            if (log.IsTraceEnabled)
            {
                log.Trace(string.Format(ESBResources.TraceCorrelationIdReceived, transportMessage.CorrelationId));

                foreach (var header in transportMessage.Headers)
                {
                    log.Trace(string.Format(ESBResources.TraceTransportHeaderReceived, header.Key, header.Value));
                }

                log.Trace(string.Format(ESBResources.MessageHandlerInvoke,
                                        transportMessage.MessageType,
                                        transportMessage.MessageId,
                                        handler.GetType().FullName));
            }

            IServiceBusTransactionScope scope = null;

            try
            {
                if (!pipelineEvent.GetHasJournalQueue())
                {
                    scope = bus.Configuration.TransactionScopeFactory.Create();
                }

                if (bus.Configuration.HasIdempotenceTracker)
                {
                    bus.Configuration.IdempotenceTracker.Add(transportMessage);

                    if (log.IsTraceEnabled)
                    {
                        log.Trace(string.Format(ESBResources.TraceIdempotenceTrackerAdd, transportMessage.MessageType,
                                                transportMessage.MessageId));
                    }
                }

                method.Invoke(handler, new[]
                {
                    Activator.CreateInstance(contextType,
                                             new[]
                    {
                        bus,
                        transportMessage,
                        message,
                        pipelineEvent.GetActiveState()
                    })
                });

                if (scope != null)
                {
                    scope.Complete();
                }
            }
            catch (Exception ex)
            {
                var exception = ex.TrimLeading <TargetInvocationException>();

                bus.Events.OnHandlerException(
                    this,
                    new HandlerExceptionEventArgs(
                        pipelineEvent,
                        handler,
                        transportMessage,
                        message,
                        pipelineEvent.GetWorkQueue(),
                        pipelineEvent.GetErrorQueue(),
                        exception));

                throw exception;
            }
            finally
            {
                if (scope != null)
                {
                    scope.Dispose();
                }
            }
        }