Exemplo n.º 1
0
        public async Task ProcessAsync(IInvocationContext context, Message message)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }
            if (message == null)
            {
                throw new ArgumentNullException(nameof(message));
            }

            var messageContext = new MessageInvocationContext(context.Principal, message, this);

            // when messages arrive through the listener there is not difference between
            // messages and queries, since the result should be delivered over the queue.
            if (IsQuery(message.Body))
            {
                await InvokeQueryHandler(messageContext, message);
            }
            else
            {
                await InvokeMessageHandlers(messageContext, message);
            }


            // someone else is taking care of the outbound messages
            if (_outboundMessageRouter != null)
            {
                Logger?.Invoke(LogLevel.Debug, "", "Invoking IOutboundMessageRouter.");
                await _outboundMessageRouter.SendAsync(messageContext);
            }
            foreach (var msg in messageContext.OutboundMessages)
            {
                Logger?.Invoke(LogLevel.Info, message.MessageId.ToString("N"), $"Sending {msg.Body.GetType()}");
                await context.SendAsync(msg);
            }

            foreach (var msg in messageContext.Replies)
            {
                Logger?.Invoke(LogLevel.Info, message.MessageId.ToString("N"), $"Replying with {msg.Body.GetType()}");
                await context.ReplyAsync(msg);
            }
        }
Exemplo n.º 2
0
        private async Task InvokeQueryHandler(MessageInvocationContext context, Message message)
        {
            var resultType = GetQueryResultType(message.Body);

            var handlerType = typeof(IQueryHandler <,>).MakeGenericType(message.Body.GetType(), resultType);
            var handlers    = _scope.Create(handlerType).ToList();

            if (handlers.Count == 0)
            {
                throw new NoHandlerRegisteredException($"Missing handler for query '{message.Body}'.");
            }
            if (handlers.Count > 1)
            {
                throw new OnlyOneQueryHandlerAllowedException(
                          $"Queries may only have one handler, '{message.Body}' got [{string.Join(", ", handlers.Select(x => x.GetType().FullName))}].");
            }
            var handler = handlers[0];

            Task      task;
            Stopwatch sw    = null;
            var       args1 = new InvokingHandlerEventArgs(_scope, handler, message)
            {
                Principal = context.Principal
            };

            try
            {
                if (HandlerInvoked != null)
                {
                    sw = Stopwatch.StartNew();
                }

                InvokingHandler?.Invoke(this, args1);

                task = (Task)handler
                       .GetType()
                       .GetMethod("HandleAsync")
                       .Invoke(handler, new[] { context, message.Body });
                await task;

                sw?.Stop();
                var e = new HandlerInvokedEventArgs(_scope, handler, message, args1, sw?.Elapsed ?? TimeSpan.Zero)
                {
                    Principal = context.Principal
                };
                HandlerInvoked?.Invoke(this, e);
            }
            catch (Exception ex)
            {
                var e = new HandlerInvokedEventArgs(_scope, handler, message, args1.ApplicationState,
                                                    sw?.Elapsed ?? TimeSpan.Zero)
                {
                    Exception = ex
                };
                HandlerInvoked?.Invoke(this, e);

                ExceptionDispatchInfo.Capture(ex).Throw();
                return;
            }

            var resultProperty = typeof(Task <>).MakeGenericType(resultType).GetProperty("Result");
            var result         = resultProperty.GetValue(task);
            await context.ReplyAsync(result);
        }