static object[] GetArguments(JsonRpcRequest request, MethodInfo methodInfo) { var methodParams = methodInfo.GetParameters(); var args = new object[methodParams.Length]; for (var i = 0; i < methodParams.Length; i++) { if (i >= request.Params.Length) continue; var jsonArg = request.Params[i]; args[i] = jsonArg; } return args; }
public JsonRpcResponse Invoke(object service, JsonRpcRequest request) { var serviceType = service.GetType(); var methods = serviceType.GetMethods().Where(m => string.Equals(m.Name, request.Method, StringComparison.OrdinalIgnoreCase)).ToList(); if (methods.Count == 0) { throw new MissingMethodException(serviceType.FullName, request.Method); } var method = SelectMethod(methods, request); var args = GetArguments(request, method); var result = method.Invoke(service, args); return new JsonRpcResponse {Id = request.Id, Result = result}; }
static JsonRpcResponse CreateError(Exception ex, JsonRpcRequest request) { Log.Error(ex.Message); Log.Error(ex.ToString()); return new JsonRpcResponse { Id = request == null ? null : request.Id, Error = new JsonRpcError {Code = ex.GetType().Name, Message = ex.Message, Data = ex.ToString()} }; }
static MethodInfo SelectMethod(IList<MethodInfo> methods, JsonRpcRequest request) { var argumentTypes = request.Params.Select(s => s == null ? null : s.GetType()).ToList(); var matches = new List<MethodInfo>(); foreach (var method in methods) { var parameters = method.GetParameters(); if (parameters.Length != argumentTypes.Count) { continue; } var isMatch = true; for (var i = 0; i < parameters.Length; i++) { var paramType = parameters[i].ParameterType; var argType = argumentTypes[i]; if (argType == null && paramType.IsValueType) { isMatch = false; break; } if (argType != null && !paramType.IsAssignableFrom(argType)) { isMatch = false; break; } } if (isMatch) { matches.Add(method); } } if (matches.Count == 1) return matches[0]; var message = new StringBuilder(); if (matches.Count > 1) { message.AppendLine("More than one possible match for the requested service method was found given the argument types. The matches were:"); foreach (var match in matches) { message.AppendLine(" - " + match); } } else { message.AppendLine("Could not decide which candidate to call out of the following methods:"); foreach (var match in methods) { message.AppendLine(" - " + match); } } message.AppendLine("The request arguments were:"); message.AppendLine(string.Join(", ", argumentTypes.Select(t => t == null ? "<null>" : t.Name))); throw new AmbiguousMatchException(message.ToString()); }
JsonRpcRequest CreateRequest(IMethodMessage methodCall) { var activityId = Guid.NewGuid(); var method = ((MethodInfo) methodCall.MethodBase); var request = new JsonRpcRequest { Id = contractType.Name + "::" + method.Name + "[" + Interlocked.Increment(ref callId) + "] / " + activityId, ActivityId = activityId, Service = contractType.Name, Method = method.Name, Params = methodCall.Args }; return request; }
JsonRpcResponse DispatchRequest(JsonRpcRequest request) { return rpcClient.Post(endPoint, request); }