예제 #1
0
        /// <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);
        }
예제 #2
0
        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));
                }
            };
        }