InvokeWithCollectionAsync(
            IReadOnlyCollection <object> messages,
            SubscribedMethod subscribedMethod,
            object?[] arguments,
            IEnumerableMessageArgumentResolver enumerableResolver,
            bool executeAsync)
        {
            if (messages.Count == 1 && messages.AsReadOnlyList()[0] is IMessageStreamProvider streamProvider &&
                streamProvider.AllowSubscribeAsEnumerable &&
                enumerableResolver is IStreamEnumerableMessageArgumentResolver resolverFromStreamProvider)
            {
                return(InvokeWithStreamEnumerable(
                           messages,
                           subscribedMethod,
                           arguments,
                           resolverFromStreamProvider));
            }

            messages = FilterMessagesAndUnwrapEnvelopes(messages, subscribedMethod).ToList();

            if (messages.Count == 0)
            {
                return(messages, null);
            }

            var target = subscribedMethod.ResolveTargetType(_serviceProvider);

            arguments[0] = enumerableResolver.GetValue(messages, subscribedMethod.MessageType);

            var returnValue = await InvokeAsync(target, subscribedMethod.MethodInfo, arguments, executeAsync)
                              .ConfigureAwait(false);

            return(messages, new[] { returnValue });
        }
        InvokeForEachMessageAsync(
            IReadOnlyCollection <object> messages,
            SubscribedMethod subscribedMethod,
            object?[] arguments,
            ISingleMessageArgumentResolver singleResolver,
            bool executeAsync)
        {
            messages = FilterMessagesAndUnwrapEnvelopes(messages, subscribedMethod).ToList();

            if (messages.Count == 0)
            {
                return(messages, null);
            }

            var target = subscribedMethod.ResolveTargetType(_serviceProvider);

            var returnValues = await messages
                               .SelectAsync(
                message =>
            {
                arguments[0] = singleResolver.GetValue(message);
                return(InvokeAsync(target, subscribedMethod.MethodInfo, arguments, executeAsync));
            })
                               .ConfigureAwait(false);

            return(messages, returnValues.ToList());
        }
Example #3
0
        private static object InvokeWithStreamEnumerable(
            IMessageStreamProvider messageStreamProvider,
            SubscribedMethod subscribedMethod,
            object?[] arguments,
            IStreamEnumerableMessageArgumentResolver streamEnumerableResolver,
            IServiceProvider serviceProvider)
        {
            var target = subscribedMethod.ResolveTargetType(serviceProvider);

            var lazyStream = streamEnumerableResolver.GetValue(
                messageStreamProvider,
                subscribedMethod.MessageType,
                subscribedMethod.Filters);

            return(Task.Run(
                       async() =>
            {
                try
                {
                    await lazyStream.WaitUntilCreatedAsync().ConfigureAwait(false);

                    arguments[0] = lazyStream.Value;
                }
                catch (OperationCanceledException)
                {
                    return;
                }

                await subscribedMethod.MethodInfo.InvokeWithActivityWithoutBlockingAsync(
                    target,
                    arguments)
                .ConfigureAwait(false);
            }));
        }
        public async Task <IEnumerable <object> > Invoke(SubscribedMethod method, IEnumerable <object> messages, bool executeAsync)
        {
            var(messageArgumentResolver, messageType) = _argumentsResolver.GetMessageArgumentResolver(method);

            if (messageArgumentResolver == null)
            {
                return(Enumerable.Empty <object>());
            }

            messages = messages.OfType(messageType);

            if (!messages.Any())
            {
                return(Enumerable.Empty <object>());
            }

            var target          = method.ResolveTargetType(_serviceProvider);
            var parameterValues = GetShiftedParameterValuesArray(method);

            IEnumerable <object> returnValues;

            switch (messageArgumentResolver)
            {
            case ISingleMessageArgumentResolver singleResolver:
                returnValues = (await messages
                                .OfType(messageType)
                                .SelectAsync(
                                    message =>
                {
                    parameterValues[0] = singleResolver.GetValue(message);
                    return(Invoke(target, method, parameterValues, executeAsync));
                },
                                    method.IsParallel,
                                    method.MaxDegreeOfParallelism))
                               .ToList();
                break;

            case IEnumerableMessageArgumentResolver enumerableResolver:
                parameterValues[0] = enumerableResolver.GetValue(messages, messageType);

                returnValues = new[] { await Invoke(target, method, parameterValues, executeAsync) };
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            return(await _returnValueHandler.HandleReturnValues(returnValues, executeAsync));
        }
Example #5
0
        private static Task <object?> InvokeWithSingleMessageAsync(
            object message,
            SubscribedMethod subscribedMethod,
            object?[] arguments,
            ISingleMessageArgumentResolver singleResolver,
            IServiceProvider serviceProvider,
            bool executeAsync)
        {
            message = UnwrapEnvelopeIfNeeded(message, subscribedMethod);

            var target = subscribedMethod.ResolveTargetType(serviceProvider);

            arguments[0] = singleResolver.GetValue(message);
            return(subscribedMethod.MethodInfo.InvokeWithActivityAsync(target, arguments, executeAsync));
        }
        InvokeWithStreamEnumerable(
            IReadOnlyCollection <object> messages,
            SubscribedMethod subscribedMethod,
            object?[] arguments,
            IStreamEnumerableMessageArgumentResolver streamEnumerableResolver)
        {
            var streamProviders = FilterMessageStreamEnumerableMessages(messages, subscribedMethod).ToArray();

            if (streamProviders.Length == 0)
            {
                return(streamProviders, null);
            }

            var target = subscribedMethod.ResolveTargetType(_serviceProvider);

            var resultTasks = streamProviders
                              .Select(
                streamProvider =>
            {
                var lazyStream = streamEnumerableResolver.GetValue(
                    streamProvider,
                    subscribedMethod.MessageType);

                return(Task.Run(
                           async() =>
                {
                    try
                    {
                        await lazyStream.WaitUntilCreated().ConfigureAwait(false);

                        arguments[0] = lazyStream.Value;
                    }
                    catch (OperationCanceledException)
                    {
                        return;
                    }

                    await InvokeWithoutBlockingAsync(target, subscribedMethod.MethodInfo, arguments)
                    .ConfigureAwait(false);
                }));
            });

            return(messages, resultTasks.ToArray());
        }