Пример #1
0
        public ActionsGroupNode ReadController(Type type, AssemblyNode assemblyNode)
        {
            var name = type.Name.Replace("Controller", string.Empty);

            name = NameCleaner.Replace(name, string.Empty);
            var controller = new ActionsGroupNode(assemblyNode, name);

            var    routePrefixAttribute = type.GetTypeInfo().GetCustomAttribute <RouteAttribute>(false) ?? type.GetTypeInfo().GetCustomAttribute <RouteAttribute>();
            string routePrefix          = routePrefixAttribute != null ? routePrefixAttribute.Template : "todo";

            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);
        }
Пример #2
0
        private void WriteController(ActionsGroupNode controllerNode, bool knockout)
        {
            var dependencies = new Dependencies
            {
                PrefixModules = PrefixModules.All
            };

            var controllersOutput = new StringBuilder();

            AppendFormatDocumentation(controllersOutput, controllerNode.Documentation);

            controllersOutput.AppendLine($"export class {controllerNode.Name}Controller {{");
            controllersOutput.AppendLine("\tconstructor(private client: helpers.ApiClient) {}");
            WriteActions(controllerNode, controllersOutput, knockout, dependencies);
            controllersOutput.AppendLine("}");

            controllersOutput.AppendLine();

            var moduleName = StringHelpers.ToCamelCase(controllerNode.Name);

            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}\";");
            if (knockout)
            {
                if (dependencies.Views)
                {
                    result.AppendLine("import * as views from \"../views\";");
                }
                if (dependencies.Enums)
                {
                    result.AppendLine("import * as enums from \"../enums\";");
                }

                if (dependencies.KoViews)
                {
                    result.AppendLine("import * as koViews from \"./views\";");
                }
            }
            else
            {
                if (dependencies.Enums)
                {
                    result.AppendLine("import * as enums from \"./enums\";");
                }
                if (dependencies.Views)
                {
                    result.AppendLine("import * as views from \"./views\";");
                }
            }
            result.AppendLine();
            result.Append(controllersOutput);

            OutputModules.Add(knockout ? $"ko/{moduleName}" : moduleName, result.ToString());
        }
Пример #3
0
        private void WriteActions(ActionsGroupNode controllerNode, StringBuilder controllersOutput, bool knockout, Dependencies dependencies)
        {
            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, knockout, dependencies);
            }
        }
Пример #4
0
        public ActionNode?ReadAction(string routePrefix, MethodInfo methodInfo, ActionsGroupNode actionsGroup)
        {
            string?      route        = null;
            ActionMethod actionMethod = ActionMethod.Unknown;

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


            var routeAttribute = methodInfo.GetCustomAttribute <RouteAttribute>();

            if (routeAttribute != null)
            {
                route = routeAttribute.Template;
            }

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

            if (actionMethod == ActionMethod.Unknown)
            {
                if (methodInfo.Name.StartsWith("Get", StringComparison.OrdinalIgnoreCase))
                {
                    actionMethod = ActionMethod.Get;
                }
                else if (methodInfo.Name.StartsWith("Post", StringComparison.OrdinalIgnoreCase))
                {
                    actionMethod = ActionMethod.Post;
                }
                else if (methodInfo.Name.StartsWith("Put", StringComparison.OrdinalIgnoreCase))
                {
                    actionMethod = ActionMethod.Put;
                }
                else if (methodInfo.Name.StartsWith("Delete", StringComparison.OrdinalIgnoreCase))
                {
                    actionMethod = 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}";
            }
            route = route.Replace("[controller]", actionsGroup.Name);

            var actionNode = new ActionNode(actionsGroup, methodInfo.Name, route);

            actionNode.Type  = actionMethod;
            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);
                actionNode.Parameters.Add(parameter);
                if (parameter.Position == ParameterPosition.Body)
                {
                    parameter.Type.Class?.SetWritable();
                }
            }

            ContextualType returnType = methodInfo.ReturnParameter.ToContextualParameter();

            if (returnType.Type.IsGenericType && returnType.Type.GetGenericTypeDefinition() == typeof(Task <>))
            {
                returnType = returnType.GenericArguments[0];
            }

            if (returnType.Type.IsGenericType && returnType.Type.GetGenericTypeDefinition() == typeof(ActionResult <>))
            {
                returnType = returnType.GenericArguments[0];
            }

            if (!returnType.Type.GetInterfaces().Contains(typeof(IActionResult)) && returnType.Type != typeof(IActionResult) && returnType.Type != typeof(Task) &&
                returnType.Type != typeof(void))
            {
                var returnDocumentation = methodNode?.Element("returns");
                actionNode.Return = ReadReturn(returnType, actionsGroup.Assembly, returnDocumentation, actionNode);
            }

            return(actionNode);
        }