Exemplo n.º 1
0
        public MessageAssembler(MethodInfo operation)
        {
            Operation  = operation;
            Parameters = operation.GetParameters();

            ValidateSignature();

            (ResponseType, ResponseTypeIndex, HeaderResponseType, HeaderResponseTypeInput) = GetResponseType(operation.ReturnType);
            (RequestType, RequestTypeInput, HeaderRequestType, HeaderRequestTypeInput)     = GetRequestType();
            ContextInput  = GetContextInput();
            OperationType = GetOperationType();
            IsAsync       = ReflectionTools.IsTask(Operation.ReturnType);
        }
Exemplo n.º 2
0
        private MethodType GetOperationType()
        {
            var returnType = Operation.ReturnType;

            if (ReflectionTools.IsTask(returnType))
            {
                var args = returnType.GenericTypeArguments;
                returnType = args.Length == 0 ? returnType : args[0];
            }

            var responseIsStreaming = ReflectionTools.IsAsyncEnumerable(returnType) ||
                                      (ReflectionTools.IsValueTuple(returnType) && returnType.GenericTypeArguments.Any(ReflectionTools.IsAsyncEnumerable));

            var requestIsStreaming = Parameters.Select(i => i.ParameterType).Any(ReflectionTools.IsAsyncEnumerable);

            if (responseIsStreaming)
            {
                return(requestIsStreaming ? MethodType.DuplexStreaming : MethodType.ServerStreaming);
            }

            return(requestIsStreaming ? MethodType.ClientStreaming : MethodType.Unary);
        }
Exemplo n.º 3
0
 private static bool IsDataParameter(Type type)
 {
     return(!ReflectionTools.IsTask(type) &&
            !IsContextParameter(type) &&
            !ReflectionTools.IsStream(type));
 }
Exemplo n.º 4
0
        private (Type ResponseType, int Index, Type?HeaderType, int[] HeaderIndexes) GetResponseType(Type returnType)
        {
            if (returnType == typeof(void))
            {
                return(typeof(Message), 0, null, Array.Empty <int>());
            }

            var responseType = returnType;

            if (ReflectionTools.IsTask(returnType))
            {
                if (!returnType.IsGenericType)
                {
                    return(typeof(Message), 0, null, Array.Empty <int>());
                }

                responseType = returnType.GenericTypeArguments[0];
            }

            if (ReflectionTools.IsValueTuple(responseType) && responseType.GenericTypeArguments.Any(ReflectionTools.IsAsyncEnumerable))
            {
                if (!ReflectionTools.IsTask(returnType))
                {
                    ThrowInvalidSignature("Wrap return type with Task<> or ValueTask<>.");
                }

                var genericArguments = responseType.GenericTypeArguments;
                if (genericArguments.Length == 1)
                {
                    ThrowInvalidSignature("Unwrap return type from ValueTuple<>.");
                }

                var streamIndex   = -1;
                var headerIndexes = new List <int>();
                var headerTypes   = new List <Type>();
                for (var i = 0; i < genericArguments.Length; i++)
                {
                    var genericArgument = genericArguments[i];
                    if (ReflectionTools.IsAsyncEnumerable(genericArgument))
                    {
                        responseType = genericArgument.GenericTypeArguments[0];
                        if (streamIndex >= 0 || IsContextParameter(responseType) || !IsDataParameter(responseType))
                        {
                            ThrowInvalidSignature();
                        }

                        streamIndex = i;
                    }
                    else if (IsContextParameter(genericArgument) || !IsDataParameter(genericArgument))
                    {
                        ThrowInvalidSignature();
                    }
                    else
                    {
                        headerIndexes.Add(i);
                        headerTypes.Add(genericArgument);
                    }
                }

                return(
                    MessageBuilder.GetMessageType(responseType),
                    streamIndex,
                    MessageBuilder.GetMessageType(headerTypes.ToArray()),
                    headerIndexes.ToArray());
            }

            if (ReflectionTools.IsAsyncEnumerable(responseType))
            {
                responseType = responseType.GenericTypeArguments[0];
            }

            if (IsContextParameter(responseType) || !IsDataParameter(responseType))
            {
                ThrowInvalidSignature();
            }

            return(MessageBuilder.GetMessageType(responseType), 0, null, Array.Empty <int>());
        }
Exemplo n.º 5
0
 public void IsTask(Type type, bool expected)
 {
     ReflectionTools.IsTask(type).ShouldBe(expected);
 }