Exemplo n.º 1
0
    public HubMethodDescriptor(ObjectMethodExecutor methodExecutor, IServiceProviderIsService?serviceProviderIsService, IEnumerable <IAuthorizeData> policies)
    {
        MethodExecutor = methodExecutor;

        NonAsyncReturnType = (MethodExecutor.IsMethodAsync)
            ? MethodExecutor.AsyncResultType !
            : MethodExecutor.MethodReturnType;

        foreach (var returnType in NonAsyncReturnType.GetInterfaces().Concat(NonAsyncReturnType.AllBaseTypes()))
        {
            if (!returnType.IsGenericType)
            {
                continue;
            }

            var openReturnType = returnType.GetGenericTypeDefinition();

            if (openReturnType == typeof(IAsyncEnumerable <>))
            {
                StreamReturnType = returnType.GetGenericArguments()[0];
                _makeCancelableEnumeratorMethodInfo = MakeCancelableAsyncEnumeratorMethod;
                break;
            }

            if (openReturnType == typeof(ChannelReader <>))
            {
                StreamReturnType = returnType.GetGenericArguments()[0];
                _makeCancelableEnumeratorMethodInfo = MakeAsyncEnumeratorFromChannelMethod;
                break;
            }
        }

        // Take out synthetic arguments that will be provided by the server, this list will be given to the protocol parsers
        ParameterTypes = methodExecutor.MethodParameters.Where((p, index) =>
        {
            // Only streams can take CancellationTokens currently
            if (IsStreamResponse && p.ParameterType == typeof(CancellationToken))
            {
                HasSyntheticArguments = true;
                return(false);
            }
            else if (ReflectionHelper.IsStreamingType(p.ParameterType, mustBeDirectType: true))
            {
                if (StreamingParameters == null)
                {
                    StreamingParameters = new List <Type>();
                }

                StreamingParameters.Add(p.ParameterType.GetGenericArguments()[0]);
                HasSyntheticArguments = true;
                return(false);
            }
            else if (p.CustomAttributes.Any(a => typeof(IFromServiceMetadata).IsAssignableFrom(a.AttributeType)) ||
                     serviceProviderIsService?.IsService(p.ParameterType) == true)
            {
                if (index >= 64)
                {
                    throw new InvalidOperationException(
                        "Hub methods can't use services from DI in the parameters after the 64th parameter.");
                }
                _isServiceArgument   |= (1UL << index);
                HasSyntheticArguments = true;
                return(false);
            }
            return(true);
        }).Select(p => p.ParameterType).ToArray();

        if (HasSyntheticArguments)
        {
            OriginalParameterTypes = methodExecutor.MethodParameters.Select(p => p.ParameterType).ToArray();
        }

        Policies = policies.ToArray();
    }
Exemplo n.º 2
0
        public HubMethodDescriptor(ObjectMethodExecutor methodExecutor, IEnumerable <IAuthorizeData> policies)
        {
            MethodExecutor = methodExecutor;

            NonAsyncReturnType = (MethodExecutor.IsMethodAsync)
                ? MethodExecutor.AsyncResultType !
                : MethodExecutor.MethodReturnType;

            foreach (var returnType in NonAsyncReturnType.GetInterfaces().Concat(NonAsyncReturnType.AllBaseTypes()))
            {
                if (!returnType.IsGenericType)
                {
                    continue;
                }

                var openReturnType = returnType.GetGenericTypeDefinition();

                if (openReturnType == typeof(IAsyncEnumerable <>))
                {
                    StreamReturnType = returnType.GetGenericArguments()[0];
                    _makeCancelableEnumeratorMethodInfo = MakeCancelableAsyncEnumeratorMethod;
                    break;
                }

                if (openReturnType == typeof(ChannelReader <>))
                {
                    StreamReturnType = returnType.GetGenericArguments()[0];
                    _makeCancelableEnumeratorMethodInfo = MakeAsyncEnumeratorFromChannelMethod;
                    break;
                }
            }

            // Take out synthetic arguments that will be provided by the server, this list will be given to the protocol parsers
            ParameterTypes = methodExecutor.MethodParameters.Where(p =>
            {
                // Only streams can take CancellationTokens currently
                if (IsStreamResponse && p.ParameterType == typeof(CancellationToken))
                {
                    HasSyntheticArguments = true;
                    return(false);
                }
                else if (ReflectionHelper.IsStreamingType(p.ParameterType, mustBeDirectType: true))
                {
                    if (StreamingParameters == null)
                    {
                        StreamingParameters = new List <Type>();
                    }

                    StreamingParameters.Add(p.ParameterType.GetGenericArguments()[0]);
                    HasSyntheticArguments = true;
                    return(false);
                }
                return(true);
            }).Select(p => p.ParameterType).ToArray();

            if (HasSyntheticArguments)
            {
                OriginalParameterTypes = methodExecutor.MethodParameters.Select(p => p.ParameterType).ToArray();
            }

            Policies = policies.ToArray();
        }