/// <summary> /// Generates POST routes automatically for the a NancyModule. /// </summary> /// <typeparam name="TBase">The type of the service (must be an interface)</typeparam> /// <param name="module">The NancyModule in which the routes will be created</param> /// <param name="implementation">An implementation of the service interface type</param> public static CableRouteSchema RegisterRoutesFor <TBase>(NancyModule module, TBase implementation) { var baseType = typeof(TBase); var type = implementation.GetType(); var baseTypeName = TypeName(baseType); var serviceName = TypeName(type); var routeSchema = new CableRouteSchema { ServiceInterface = baseTypeName, ServiceName = serviceName }; CheckMethodOverloading <TBase>(); var defaultMethods = new string[] { "Equals", "ToString", "GetHashCode", "GetType" }; var publicMethods = baseType.GetMethods().Where(method => !defaultMethods.Contains(method.Name)); foreach (var method in publicMethods) { if (method.ContainsGenericParameters) { throw new ArgumentException($"Method {method.Name} contains generic type parameters, this is not supported."); } RegisterRoute <TBase>(implementation, method, module, routeSchema); } return(routeSchema); }
static void RegisterRoute <TBase>(object implementation, MethodInfo method, NancyModule module, CableRouteSchema routeSchema) { var typeName = typeof(TBase).Name; var url = urlMapper(typeName, method.Name); var isReturningTask = method.ReturnType.BaseType == typeof(Task); routeSchema.Routes.Add(new CableRoute { Method = method.Name, ParameterTypes = method.GetParameters().Select(p => p.ParameterType).Select(TypeName).ToList(), ReturnType = TypeName(method.ReturnType), Route = url }); module.Post[url, true] = async(ctx, token) => { try { using (var reader = new StreamReader(module.Request.Body)) { var incomingJson = await reader.ReadToEndAsync(); var inputParameters = JObject.Parse(incomingJson); var jsonParameters = inputParameters["Value"] as JArray; var parameterTypes = method.GetParameters().Select(p => p.ParameterType).ToArray(); object[] parameters = new object[parameterTypes.Length]; for (var i = 0; i < parameters.Length; i++) { var type = parameterTypes[i]; // deserialize each parameter to it's respective type var json = jsonParameters[i].ToString(); parameters[i] = Json.Deserialize(json, type); } object result = null; if (isReturningTask) { dynamic task = method.Invoke(implementation, parameters); result = await task; } else { result = method.Invoke(implementation, parameters); } return(Json.Serialize(result)); } } catch (Exception ex) { var errorData = new Dictionary <string, object>(); errorData["$exception"] = true; errorData["$exceptionMessage"] = ex.InnerException.Message; return(JsonConvert.SerializeObject(errorData)); } }; }