internal RestControllerMethodInfo(MethodInfo methodInfo, bool async)
 {
     _matchUri            = GetUriFromMethod(methodInfo);
     Async                = async;
     MethodInfo           = methodInfo;
     _validParameterTypes = GetValidParameterTypes();
     _parameterGetters    = GetParameterGetters(methodInfo);
     HasContentParameter  = TryGetContentParameterType(methodInfo, out Type contentParameterType);
     ContentParameterType = contentParameterType;
 }
        internal object GetParameterValue(ParsedUri parsedUri)
        {
            var value = parsedUri.PathParts[_pathIndex].Value;

            if (_parameterType == typeof(string))
            {
                var unescapedParameterValue = Uri.UnescapeDataString(value);
                return(Convert.ChangeType(unescapedParameterValue, _parameterType));
            }
            return(Convert.ChangeType(value, _parameterType));
        }
        internal bool Match(ParsedUri uri)
        {
            if (_matchUri.PathParts.Count != uri.PathParts.Count)
            {
                return(false);
            }

            for (var i = 0; i < _matchUri.PathParts.Count; i++)
            {
                var fromPart = _matchUri.PathParts[i];
                var toPart   = uri.PathParts[i];
                if (fromPart.PartType == PathPart.PathPartType.Argument)
                {
                    continue;
                }
                else if (!fromPart.Value.Equals(toPart.Value, StringComparison.OrdinalIgnoreCase))
                {
                    return(false);
                }
            }
            return(true);
        }
        private static ParameterValueGetter GetParameterGetter(ParameterInfo parameterInfo, ParsedUri matchUri)
        {
            var methodName         = parameterInfo.Name;
            var firstPathPartMatch = matchUri.PathParts
                                     .Select((x, i) => new { Part = x, Index = i })
                                     .Where(x => x.Part.PartType == PathPart.PathPartType.Argument)
                                     .FirstOrDefault(x => methodName.Equals(x.Part.Value, StringComparison.OrdinalIgnoreCase));

            if (firstPathPartMatch != null)
            {
                return(new ParameterValueGetter(parameterInfo.ParameterType, firstPathPartMatch.Index));
            }

            throw new Exception($"Method {methodName} not found in rest controller method uri {matchUri}.");
        }
 internal IEnumerable <object> GetParametersFromUri(ParsedUri uri)
 {
     return(_parameterGetters.Select(x => x.GetParameterValue(uri)).ToArray());
 }
        private object ExecuteAnonymousMethod(RestControllerMethodInfo info, RestRequest request, ParsedUri requestUri)
        {
            var instantiator = ObjectCache[info.MethodInfo.DeclaringType];

            object[] parameters;
            if (info.HasContentParameter && request.Content != null)
            {
                try
                {
                    var content       = (XElement)request.Content;
                    var xmlSerializer = new XmlSerializer(info.ContentParameterType);
                    using (var reader = new StringReader(content.FirstNode.ToString()))
                    {
                        object contentObj = xmlSerializer.Deserialize(reader);
                        parameters = info.GetParametersFromUri(requestUri).Concat(new[] { contentObj }).ToArray();
                    }
                }
                catch (Exception e)
                {
                    throw new Exception($"Ocorreu um erro ao desserializar o objeto de tipo {info.ContentParameterType.Name}", e);
                }
            }
            else
            {
                parameters = info.GetParametersFromUri(requestUri).ToArray();
            }

            return(info.MethodInfo.Invoke(instantiator, parameters));
        }