private static object[] TryGetParameters(JsonRpcMessage request, MethodSignature method, HashSet <string> errors, JsonSerializer jsonSerializer, string requestMethodName)
        {
            Requires.NotNull(request, nameof(request));
            Requires.NotNull(method, nameof(method));
            Requires.NotNull(errors, nameof(errors));
            Requires.NotNull(jsonSerializer, nameof(jsonSerializer));
            Requires.NotNullOrEmpty(requestMethodName, nameof(requestMethodName));

            if (!method.IsPublic)
            {
                errors.Add(string.Format(CultureInfo.CurrentCulture, Resources.MethodIsNotPublic, method));
                return(null);
            }

            // ref and out parameters aren't supported.
            if (method.HasOutOrRefParameters)
            {
                errors.Add(string.Format(CultureInfo.CurrentCulture, Resources.MethodHasRefOrOutParameters, method));
                return(null);
            }

            if (request.Parameters != null && request.Parameters.Type == JTokenType.Object)
            {
                // If the parameter passed is an object, then we want to find the matching method with the same name and the method only takes a JToken as a parameter.
                if (method.Parameters.Length != 1)
                {
                    return(null);
                }

                if (method.Parameters[0].ParameterType != typeof(JToken))
                {
                    return(null);
                }

                return(new object[] { request.Parameters });
            }

            // The number of parameters must fall within required and total parameters.
            int paramCount = request.ParameterCount;

            if (paramCount < method.RequiredParamCount || paramCount > method.TotalParamCountExcludingCancellationToken)
            {
                string methodParameterCount;
                if (method.RequiredParamCount == method.TotalParamCountExcludingCancellationToken)
                {
                    methodParameterCount = method.RequiredParamCount.ToString(CultureInfo.CurrentCulture);
                }
                else
                {
                    methodParameterCount = string.Format(CultureInfo.CurrentCulture, "{0} - {1}", method.RequiredParamCount, method.TotalParamCountExcludingCancellationToken);
                }

                errors.Add(string.Format(
                               CultureInfo.CurrentCulture,
                               Resources.MethodParameterCountDoesNotMatch,
                               method,
                               methodParameterCount,
                               request.ParameterCount));

                return(null);
            }

            // Parameters must be compatible
            try
            {
                return(request.GetParameters(method.Parameters, jsonSerializer));
            }
            catch (Exception exception)
            {
                errors.Add(string.Format(CultureInfo.CurrentCulture, Resources.MethodParametersNotCompatible, method, exception.Message));
                return(null);
            }
        }
 internal MethodSignatureAndTarget(MethodSignature signature, object?target, SynchronizationContext?perMethodSynchronizationContext)
 {
     this.Signature = signature;
     this.Target    = target;
     this.SynchronizationContext = perMethodSynchronizationContext;
 }
        private object[] TryGetParameters(JsonRpcMessage request, MethodSignature method, JsonSerializer jsonSerializer, string requestMethodName)
        {
            Requires.NotNull(request, nameof(request));
            Requires.NotNull(method, nameof(method));
            Requires.NotNull(jsonSerializer, nameof(jsonSerializer));
            Requires.NotNullOrEmpty(requestMethodName, nameof(requestMethodName));

            // ref and out parameters aren't supported.
            if (method.HasOutOrRefParameters)
            {
                this.AddErrorMessage(string.Format(CultureInfo.CurrentCulture, Resources.MethodHasRefOrOutParameters, method));
                return(null);
            }

            if (request.Parameters != null && request.Parameters.Type == JTokenType.Object)
            {
                // If the parameter passed is an object, then we want to find the matching method with the same name and the method only takes a JToken as a parameter,
                // and possibly a CancellationToken
                if (method.Parameters.Length < 1 || method.Parameters[0].ParameterType != typeof(JToken))
                {
                    return(null);
                }

                if (method.Parameters.Length > 2)
                {
                    // We don't support methods with more than two parameters.
                    return(null);
                }

                bool includeCancellationToken = method.Parameters.Length > 1 && method.Parameters[1].ParameterType == typeof(CancellationToken);

                var args = new object[includeCancellationToken ? 2 : 1];
                args[0] = request.Parameters;
                if (includeCancellationToken)
                {
                    args[1] = CancellationToken.None;
                }

                return(args);
            }

            // The number of parameters must fall within required and total parameters.
            int paramCount = request.ParameterCount;

            if (paramCount < method.RequiredParamCount || paramCount > method.TotalParamCountExcludingCancellationToken)
            {
                string methodParameterCount;
                if (method.RequiredParamCount == method.TotalParamCountExcludingCancellationToken)
                {
                    methodParameterCount = method.RequiredParamCount.ToString(CultureInfo.CurrentCulture);
                }
                else
                {
                    methodParameterCount = string.Format(CultureInfo.CurrentCulture, "{0} - {1}", method.RequiredParamCount, method.TotalParamCountExcludingCancellationToken);
                }

                this.AddErrorMessage(string.Format(
                                         CultureInfo.CurrentCulture,
                                         Resources.MethodParameterCountDoesNotMatch,
                                         method,
                                         methodParameterCount,
                                         request.ParameterCount));

                return(null);
            }

            // Parameters must be compatible
            try
            {
                return(request.GetParameters(method.Parameters, jsonSerializer));
            }
            catch (Exception exception)
            {
                this.AddErrorMessage(string.Format(CultureInfo.CurrentCulture, Resources.MethodParametersNotCompatible, method, exception.Message));
                return(null);
            }
        }