Exemplo n.º 1
0
        public ActionsGroupNode ReadController(Type type, AssemblyNode assemblyNode)
        {
            var controller = new ActionsGroupNode
            {
                Assembly = assemblyNode
            };

            string routePrefix = null;
            var routePrefixAttribute = type.GetTypeInfo().GetCustomAttribute<RouteAttribute>(false) ?? type.GetTypeInfo().GetCustomAttribute<RouteAttribute>();
            if (routePrefixAttribute != null)
            {
                routePrefix = routePrefixAttribute.Template;
            }

            controller.Name = type.Name.Replace("Controller", string.Empty);
            controller.Name = NameCleaner.Replace(controller.Name, string.Empty);
            controller.Documentation = documentation.GetDocumentation(type);

            foreach (var methodInfo in type.GetMethods().Where(x => x.IsPublic))
            {
                if (methodInfo.GetCustomAttribute<NonActionAttribute>() != null) continue;
                if (methodInfo.IsSpecialName) continue;

                var action = ReadAction(routePrefix, methodInfo, controller);
                if (action != null)
                {
                    controller.Actions.Add(action);
                }
            }
            return controller;
        }
Exemplo n.º 2
0
 public ActionNode(ActionsGroupNode actionsGroupNode, string name, string route) => (Group, Name, Route) = (actionsGroupNode, name, route);
        private void WriteController(ActionsGroupNode controllerNode)
        {
            var result = new StringBuilder();
            result.AppendLine("/* This is a generated file. Do not modify or all the changes will be lost. */");
            result.AppendLine($"import * as helpers from '{serviceHelpersModule}';");
            result.AppendLine("import * as views from './views';");
            result.AppendLine("import * as koViews from './ko-views';");

            var controllersOutput = new StringBuilder();

            AppendFormatDocumentation(controllersOutput, controllerNode.Documentation);

            controllersOutput.AppendLine($"export class {controllerNode.Name}Controller {{");
            WriteActions(controllerNode, controllersOutput);
            controllersOutput.AppendLine("}");

            controllersOutput.AppendLine();
            
            var moduleName = StringHelpers.ToCamelCase(controllerNode.Name);
           
            result.AppendLine();
            result.Append(controllersOutput);

            OutputModules.Add(moduleName, result.ToString());
        }
        private void WriteActions(ActionsGroupNode controllerNode, StringBuilder controllersOutput)
        {
            var actions = controllerNode.Actions.OrderBy(x => x.Name).ThenBy(x => x.Parameters.Count).ToArray();
            foreach (var actionNode in actions)
            {
                var methodName = StringHelpers.ToCamelCase(actionNode.Name);
                var sameName = actions.Where(x => x.Name == actionNode.Name).ToList();
                if (sameName.Count > 1)
                {
                    methodName += sameName.IndexOf(actionNode) + 1;
                }

                WriteAction(methodName, actionNode, controllersOutput, true);
                if (actionNode.Return != null && actionNode.Return.Type.IsObservable)
                    WriteAction(methodName + "T", actionNode, controllersOutput, false);
            }
        }
Exemplo n.º 5
0
        public ActionNode ReadAction(string routePrefix, MethodInfo methodInfo, ActionsGroupNode actionsGroup)
        {
            var actionNode = new ActionNode {Group = actionsGroup};

            string route = null;

            if (methodInfo.GetCustomAttribute<HttpGetAttribute>() != null)
            {
                actionNode.Type = ActionMethod.Get;
                route = methodInfo.GetCustomAttribute<HttpGetAttribute>().Template;
            }
            else if (methodInfo.GetCustomAttribute<HttpPostAttribute>() != null)
            {
                actionNode.Type = ActionMethod.Post;
                route = methodInfo.GetCustomAttribute<HttpPostAttribute>().Template;
            }
            else if (methodInfo.GetCustomAttribute<HttpPutAttribute>() != null)
            {
                actionNode.Type = ActionMethod.Put;
                route = methodInfo.GetCustomAttribute<HttpPutAttribute>().Template;
            }
            else if (methodInfo.GetCustomAttribute<HttpDeleteAttribute>() != null)
            {
                actionNode.Type = ActionMethod.Delete;
                route = methodInfo.GetCustomAttribute<HttpDeleteAttribute>().Template;
            }

            var routeAttribute = methodInfo.GetCustomAttribute<RouteAttribute>();
            if (routeAttribute != null)
            {
                route = routeAttribute.Template;
            }

            if (route == null)
            {
                return null;
            }

            if (actionNode.Type == ActionMethod.Unknown)
            {
                if (methodInfo.Name.StartsWith("Get", StringComparison.OrdinalIgnoreCase)) actionNode.Type = ActionMethod.Get;
                else if (methodInfo.Name.StartsWith("Post", StringComparison.OrdinalIgnoreCase)) actionNode.Type = ActionMethod.Post;
                else if (methodInfo.Name.StartsWith("Put", StringComparison.OrdinalIgnoreCase)) actionNode.Type = ActionMethod.Put;
                else if (methodInfo.Name.StartsWith("Delete", StringComparison.OrdinalIgnoreCase)) actionNode.Type = ActionMethod.Delete;
                else
                    return null;
            }

            // Remove type info from route
            route = Regex.Replace(route, @"{(\w+\??)(?::\w+)?}", "{$1}");
            if (route.StartsWith("~"))
            {
                route = Regex.Replace(route, @"^~/?", string.Empty);
            }
            else
            {
                route = $"{routePrefix}/{route}";
            }

            actionNode.Name = methodInfo.Name;
            actionNode.Route = route;

            var versionMatch = Regex.Match(route, @"api/v([\d\.])+");
            actionNode.Version = versionMatch.Success ? versionMatch.Groups[1].Value : null;

            var authorizeAttribute = methodInfo.GetCustomAttribute<AuthorizeAttribute>();
            if (authorizeAttribute != null)
            {
                actionNode.Authorization = authorizeAttribute.Policy ?? authorizeAttribute.Roles;
            }

            // Read documentation
            var methodNode = documentation.GetMethodDocumentation(methodInfo);

            var summary = methodNode?.Element("summary");
            if (summary != null)
            {
                actionNode.Documentation = summary.Value;
            }

            Dictionary<string, XElement> parameterNodes = null;

            if (methodNode != null)
            {
                parameterNodes = methodNode.Elements("param").ToDictionary(x => x.Attribute("name").Value);
            }

            var routeParameters = new Dictionary<string, bool>();
            var routeParametersMatches = Regex.Matches(route, @"{(\w+)(\?)?(?:\:\w+)?}");
            foreach (Match match in routeParametersMatches)
            {
                var parameter = match.Groups[1].Value;
                var optional = match.Groups[2].Value == "?";
                routeParameters.Add(parameter, optional);
            }

            foreach (var parameterInfo in methodInfo.GetParameters())
            {
                var parameter = ReadParameter(parameterInfo, parameterNodes != null && parameterNodes.ContainsKey(parameterInfo.Name) ? parameterNodes[parameterInfo.Name] : null, actionsGroup.Assembly, routeParameters, actionNode.Version);
                actionNode.Parameters.Add(parameter);
                if (parameter.Position == ParameterPosition.Body)
                {
                    parameter.Type.SetWritable();
                }
            }

            Type returnType;
            var returnTypeAttribute = methodInfo.GetCustomAttribute<ProducesResponseTypeAttribute>();
            if (returnTypeAttribute != null)
            {
                returnType = returnTypeAttribute.Type;
            }
            else
            {
                returnType = methodInfo.ReturnType;
                if (returnType.GetTypeInfo().IsGenericType && returnType.GetGenericTypeDefinition() == typeof(Task<>))
                {
                    returnType = returnType.GenericTypeArguments[0];
                }

                if (returnType.GetTypeInfo().IsGenericType && returnType.GetGenericTypeDefinition() == typeof(IHttpActionResult<>))
                {
                    returnType = returnType.GenericTypeArguments[0];
                }

                if (returnType.GetInterfaces().Contains(typeof(IActionResult)) || returnType == typeof(IActionResult) || returnType == typeof(Task))
                {
                    returnType = null;
                }
            }

            if (returnType != null && returnType != typeof(void))
            {
                var returnDocumentation = methodNode?.Element("returns");
                actionNode.Return = ReadReturn(returnType, actionsGroup.Assembly, returnDocumentation, actionNode.Version);
            }

            return actionNode;
        }