Ejemplo n.º 1
0
        public void Generate(CodeWriterBase writer, Cfg cfg)
        {
            if (writer.GetType() != typeof(WriterForCS))
            {
                throw new Exception("For the selected template is currenty only language 'CS' supported!");
            }

            var nsImports = new List <string>();

            nsImports.Add("Newtonsoft.Json");
            nsImports.Add("System");
            nsImports.Add("System.Net");

            var inputFileFullPath = Path.GetFullPath(cfg.inputFile);

            Program.AddResolvePath(Path.GetDirectoryName(inputFileFullPath));
            Assembly ass = Assembly.LoadFile(inputFileFullPath);

            Type[] svcInterfaces;
            try {
                svcInterfaces = ass.GetTypes();
            }
            catch (ReflectionTypeLoadException ex) {
                svcInterfaces = ex.Types.Where((t) => t != null).ToArray();
            }

            //transform patterns to regex
            cfg.interfaceTypeNamePattern = "^(" + Regex.Escape(cfg.interfaceTypeNamePattern).Replace("\\*", ".*?") + ")$";

            svcInterfaces = svcInterfaces.Where((Type i) => Regex.IsMatch(i.FullName, cfg.interfaceTypeNamePattern)).ToArray();

            if (!String.IsNullOrWhiteSpace(cfg.outputNamespace) && cfg.customImports.Contains(cfg.outputNamespace))
            {
                nsImports.Remove(cfg.outputNamespace);
            }
            foreach (string import in cfg.customImports.Union(nsImports).Distinct().OrderBy((s) => s))
            {
                writer.WriteImport(import);
            }

            if (!String.IsNullOrWhiteSpace(cfg.outputNamespace))
            {
                writer.WriteLine();
                writer.WriteBeginNamespace(cfg.outputNamespace);
            }

            writer.WriteLine();

            writer.WriteLineAndPush($"public partial class {cfg.connectorClassName} {{");
            writer.WriteLine();
            writer.WriteLineAndPush($"public {cfg.connectorClassName}(string url, string apiToken) {{");
            writer.WriteLine();
            writer.WriteLineAndPush("if (!url.EndsWith(\"/\")) {");
            writer.WriteLine("url = url + \"/\";");
            writer.PopAndWriteLine("}");
            writer.WriteLine();

            foreach (Type svcInt in svcInterfaces)
            {
                string endpointName = svcInt.Name;
                if (endpointName[0] == 'I' && Char.IsUpper(endpointName[1]))
                {
                    endpointName = endpointName.Substring(1);
                }
                writer.WriteLine($"_{endpointName}Client = new {endpointName}Client(url + \"{writer.Ftl(endpointName)}/\", apiToken);");
            }
            writer.WriteLine();
            writer.PopAndWriteLine("}");

            foreach (Type svcInt in svcInterfaces)
            {
                string endpointName = svcInt.Name;
                if (endpointName[0] == 'I' && Char.IsUpper(endpointName[1]))
                {
                    endpointName = endpointName.Substring(1);
                }
                string svcIntDoc = XmlCommentAccessExtensions.GetDocumentation(svcInt);

                writer.WriteLine();
                writer.WriteLine($"private {endpointName}Client _{endpointName}Client = null;");
                if (!String.IsNullOrWhiteSpace(svcIntDoc))
                {
                    writer.WriteLine($"/// <summary> {svcIntDoc} </summary>");
                }
                writer.WriteLineAndPush($"public {svcInt.Name} {endpointName} {{");
                writer.WriteLineAndPush("get {");
                writer.WriteLine($"return _{endpointName}Client;");
                writer.PopAndWriteLine("}");
                writer.PopAndWriteLine("}");
            }
            writer.WriteLine();
            writer.PopAndWriteLine("}"); //class

            foreach (Type svcInt in svcInterfaces)
            {
                string endpointName = svcInt.Name;
                if (endpointName[0] == 'I' && Char.IsUpper(endpointName[1]))
                {
                    endpointName = endpointName.Substring(1);
                }
                string svcIntDoc = XmlCommentAccessExtensions.GetDocumentation(svcInt);

                writer.WriteLine();
                if (!String.IsNullOrWhiteSpace(svcIntDoc))
                {
                    writer.WriteLine($"/// <summary> {svcIntDoc} </summary>");
                }
                writer.WriteLineAndPush($"internal partial class {endpointName}Client : {svcInt.Name} {{");
                writer.WriteLine();
                writer.WriteLine("private string _Url;");
                writer.WriteLine("private string _ApiToken;");
                writer.WriteLine();
                writer.WriteLineAndPush($"public {endpointName}Client(string url, string apiToken) {{");
                writer.WriteLine("_Url = url;");
                writer.WriteLine("_ApiToken = apiToken;");
                writer.PopAndWriteLine("}"); //constructor
                writer.WriteLine();
                writer.WriteLineAndPush($"private WebClient CreateWebClient() {{");
                writer.WriteLine("var wc = new WebClient();");
                //TODO: make customizable
                writer.WriteLine("wc.Headers.Set(\"" + cfg.authHeaderName + "\", _ApiToken);");
                writer.WriteLine("wc.Headers.Set(\"Content-Type\", \"application/json\");");
                writer.WriteLine("return wc;");
                writer.PopAndWriteLine("}"); //constructor

                foreach (MethodInfo svcMth in svcInt.GetMethods())
                {
                    string svcMthDoc = XmlCommentAccessExtensions.GetDocumentation(svcMth, true);

                    writer.WriteLine();
                    if (String.IsNullOrWhiteSpace(svcMthDoc))
                    {
                        svcMthDoc = svcMth.Name;
                    }
                    writer.WriteLine($"/// <summary> {svcMthDoc} </summary>");

                    var paramSignature = new List <string>();
                    foreach (ParameterInfo svcMthPrm in svcMth.GetParameters())
                    {
                        string svcMthPrmDoc = XmlCommentAccessExtensions.GetDocumentation(svcMthPrm);
                        if (String.IsNullOrWhiteSpace(svcMthPrmDoc))
                        {
                            svcMthPrmDoc = XmlCommentAccessExtensions.GetDocumentation(svcMthPrm.ParameterType);
                        }
                        if (!String.IsNullOrWhiteSpace(svcMthPrmDoc))
                        {
                            writer.WriteLine($"/// <param name=\"{svcMthPrm.Name}\"> {svcMthPrmDoc} </param>");
                        }

                        Type   pt  = svcMthPrm.ParameterType;
                        string pfx = "";
                        if (svcMthPrm.IsOut)
                        {
                            pt = pt.GetElementType();
                            if (svcMthPrm.IsIn)
                            {
                                pfx = "ref ";
                            }
                            else
                            {
                                pfx = "out ";
                            }
                        }

                        bool nullable;
                        var  ptName = pt.GetTypeNameSave(out nullable);
                        if (nullable)
                        {
                            ptName = ptName + "?";
                        }

                        if (svcMthPrm.IsOptional)
                        {
                            //were implementing the interface "as it is"

                            string defaultValueString = "";

                            if (svcMthPrm.DefaultValue == null)
                            {
                                defaultValueString = " = null";
                            }
                            else if (svcMthPrm.DefaultValue.GetType() == typeof(string))
                            {
                                defaultValueString = " = \"" + svcMthPrm.DefaultValue.ToString() + "\"";
                            }
                            else
                            {
                                defaultValueString = " = " + svcMthPrm.DefaultValue.ToString() + "";
                            }

                            paramSignature.Add($"{pfx}{ptName} {svcMthPrm.Name}" + defaultValueString);

                            //paramSignature.Add($"{pt} {svcMthPrm.Name} = default({ptName})");
                            //if (pt.IsValueType) {
                            //  paramSignature.Add($"{pfx}{ptName}? {svcMthPrm.Name} = null");
                            //}
                            //else {
                            //  paramSignature.Add($"{pfx}{ptName} {svcMthPrm.Name} = null");
                            //}
                        }
                        else
                        {
                            paramSignature.Add($"{pfx}{ptName} {svcMthPrm.Name}");
                        }
                    }

                    if (svcMth.ReturnType == null || svcMth.ReturnType == typeof(void))
                    {
                        writer.WriteLineAndPush($"public void {svcMth.Name}({String.Join(", ", paramSignature.ToArray())}) {{");
                    }
                    else
                    {
                        writer.WriteLineAndPush($"public {svcMth.ReturnType.Name} {svcMth.Name}({String.Join(", ", paramSignature.ToArray())}) {{");
                    }

                    writer.WriteLineAndPush($"using (var webClient = this.CreateWebClient()) {{");

                    writer.WriteLine($"string url = _Url + \"{writer.Ftl(svcMth.Name)}\";");

                    writer.WriteLineAndPush($"var args = new {svcMth.Name}Request {{");
                    int i      = 0;
                    int pCount = svcMth.GetParameters().Length;
                    foreach (ParameterInfo svcMthPrm in svcMth.GetParameters())
                    {
                        if (!svcMthPrm.IsOut)
                        {
                            i++;
                            if (i < pCount)
                            {
                                writer.WriteLine($"{svcMthPrm.Name} = {svcMthPrm.Name},");
                            }
                            else
                            {
                                writer.WriteLine($"{svcMthPrm.Name} = {svcMthPrm.Name}");
                            }
                        }
                    }
                    writer.PopAndWriteLine("};");

                    writer.WriteLine($"string rawRequest = JsonConvert.SerializeObject(args);");
                    writer.WriteLine($"string rawResponse = webClient.UploadString(url, rawRequest);");
                    writer.WriteLine($"var result = JsonConvert.DeserializeObject<{svcMth.Name}Response>(rawResponse);");

                    foreach (ParameterInfo svcMthPrm in svcMth.GetParameters())
                    {
                        if (svcMthPrm.IsOut)
                        {
                            writer.WriteLine($"{svcMthPrm.Name} = result.{svcMthPrm.Name};");
                        }
                    }

                    if (cfg.throwClientExecptionsFromFaultProperty)
                    {
                        writer.WriteLineAndPush($"if(result.fault != null){{");
                        writer.WriteLine($"throw new Exception(result.fault);");
                        writer.PopAndWriteLine("}");
                    }

                    if (svcMth.ReturnType == null || svcMth.ReturnType == typeof(void))
                    {
                        writer.WriteLine($"return;");
                    }
                    else
                    {
                        writer.WriteLine($"return result.@return;");
                    }

                    writer.PopAndWriteLine("}"); //using
                    writer.PopAndWriteLine("}"); //method
                }//foreach Method

                writer.WriteLine();
                writer.PopAndWriteLine("}"); //class
            }//foreach Interface

            if (!String.IsNullOrWhiteSpace(cfg.outputNamespace))
            {
                writer.WriteLine();
                writer.WriteEndNamespace();
            }
        }
Ejemplo n.º 2
0
        public void Generate(CodeWriterBase writer, Cfg cfg)
        {
            if (writer.GetType() != typeof(WriterForCS))
            {
                throw new Exception("For the selected template is currenty only language 'CS' supported!");
            }

            var nsImports = new List <string>();

            nsImports.Add("Microsoft.AspNetCore.Mvc");
            nsImports.Add("Microsoft.Extensions.Logging");
            nsImports.Add("Security");
            if (cfg.generateSwashbuckleAttributesForControllers)
            {
                nsImports.Add("Swashbuckle.AspNetCore.Annotations");
            }
            nsImports.Add("System");
            nsImports.Add("System.Collections.Generic");
            nsImports.Add("System.Linq");
            nsImports.Add("System.Net");

            var inputFileFullPath = Path.GetFullPath(cfg.inputFile);

            Program.AddResolvePath(Path.GetDirectoryName(inputFileFullPath));
            Assembly ass = Assembly.LoadFile(inputFileFullPath);

            Type[] svcInterfaces;
            try {
                svcInterfaces = ass.GetTypes();
            }
            catch (ReflectionTypeLoadException ex) {
                svcInterfaces = ex.Types.Where((t) => t != null).ToArray();
            }

            //transform patterns to regex
            cfg.interfaceTypeNamePattern = "^(" + Regex.Escape(cfg.interfaceTypeNamePattern).Replace("\\*", ".*?") + ")$";

            svcInterfaces = svcInterfaces.Where((Type i) => Regex.IsMatch(i.FullName, cfg.interfaceTypeNamePattern)).ToArray();

            if (!String.IsNullOrWhiteSpace(cfg.outputNamespace) && cfg.customImports.Contains(cfg.outputNamespace))
            {
                nsImports.Remove(cfg.outputNamespace);
            }
            foreach (string import in cfg.customImports.Union(nsImports).Distinct().OrderBy((s) => s))
            {
                writer.WriteImport(import);
            }

            if (!String.IsNullOrWhiteSpace(cfg.outputNamespace))
            {
                writer.WriteLine();
                writer.WriteBeginNamespace(cfg.outputNamespace);
            }

            //collect models
            //var directlyUsedModelTypes = new List<Type>();
            //var wrappers = new Dictionary<String, StringBuilder>();
            foreach (Type svcInt in svcInterfaces)
            {
                //if(!nsImports.Contains(svcInt.Namespace)){
                //  nsImports.Add(svcInt.Namespace);
                //}
                string svcIntDoc    = XmlCommentAccessExtensions.GetDocumentation(svcInt);
                string endpointName = svcInt.Name;

                if (endpointName[0] == 'I' && Char.IsUpper(endpointName[1]))
                {
                    endpointName = endpointName.Substring(1);
                }

                writer.WriteLine();
                writer.WriteLine("[ApiController]");
                writer.WriteLine($"[Route(\"{writer.Ftl(endpointName)}\")]");
                writer.WriteLineAndPush($"public partial class {endpointName}Controller : ControllerBase {{");
                writer.WriteLine();
                writer.WriteLine($"private readonly ILogger<{endpointName}Controller> _Logger;");
                writer.WriteLine($"private readonly {svcInt.Name} _{endpointName};");
                writer.WriteLine();
                writer.WriteLineAndPush($"public {endpointName}Controller(ILogger<{endpointName}Controller> logger, {svcInt.Name} {writer.Ftl(endpointName)}) {{");
                writer.WriteLine($"_Logger = logger;");
                writer.WriteLine($"_{endpointName} = {writer.Ftl(endpointName)};");
                writer.PopAndWriteLine("}");

                foreach (MethodInfo svcMth in svcInt.GetMethods())
                {
                    string svcMthDoc = XmlCommentAccessExtensions.GetDocumentation(svcMth, true);

                    writer.WriteLine();
                    if (String.IsNullOrWhiteSpace(svcMthDoc))
                    {
                        svcMthDoc = svcMth.Name;
                    }
                    writer.WriteLine($"/// <summary> {svcMthDoc} </summary>");
                    writer.WriteLine($"/// <param name=\"args\"> request capsule containing the method arguments </param>");

                    if (!String.IsNullOrWhiteSpace(cfg.customAttributesPerControllerMethod))
                    {
                        writer.WriteLine("[" + cfg.customAttributesPerControllerMethod.Replace("{C}", endpointName).Replace("{O}", svcMth.Name) + "]");
                    }
                    writer.WriteLine($"[HttpPost(\"{writer.Ftl(svcMth.Name)}\"), Produces(\"application/json\")]");

                    string swaggerBodyAttrib = "";
                    if (cfg.generateSwashbuckleAttributesForControllers)
                    {
                        swaggerBodyAttrib = "[SwaggerRequestBody(Required = true)]";
                        string escDesc = svcMthDoc.Replace("\\", "\\\\").Replace("\"", "\\\"");
                        nsImports.Add($"[SwaggerOperation(OperationId = nameof({svcMth.Name}), Description = \"{escDesc}\")]");
                    }

                    writer.WriteLineAndPush($"public {svcMth.Name}Response {svcMth.Name}([FromBody]{swaggerBodyAttrib} {svcMth.Name}Request args) {{");
                    writer.WriteLineAndPush("try {");
                    writer.WriteLine($"var response = new {svcMth.Name}Response();");

                    var @params = new List <string>();
                    foreach (ParameterInfo svcMthPrm in svcMth.GetParameters())
                    {
                        if (svcMthPrm.IsOut)
                        {
                            if (svcMthPrm.IsIn)
                            {
                                writer.WriteLine($"response.{writer.Ftl(svcMthPrm.Name)} = args.{writer.Ftl(svcMthPrm.Name)}; //shift IN-OUT value");
                            }
                            @params.Add($"response.{writer.Ftl(svcMthPrm.Name)}");
                        }
                        else
                        {
                            if (svcMthPrm.IsOptional)
                            {
                                string defaultValueString = "";
                                if (svcMthPrm.DefaultValue == null)
                                {
                                    defaultValueString = "null";
                                }
                                else if (svcMthPrm.DefaultValue.GetType() == typeof(string))
                                {
                                    defaultValueString = "\"" + svcMthPrm.DefaultValue.ToString() + "\"";
                                }
                                else
                                {
                                    defaultValueString = svcMthPrm.DefaultValue.ToString();
                                }

                                if (svcMthPrm.ParameterType.IsValueType)
                                {
                                    @params.Add($"(args.{writer.Ftl(svcMthPrm.Name)}.HasValue ? args.{writer.Ftl(svcMthPrm.Name)}.Value : {defaultValueString})");
                                }
                                else
                                {
                                    //here 'null' will be used
                                    @params.Add($"args.{writer.Ftl(svcMthPrm.Name)}");

                                    //@params.Add($"(args.{writer.Ftl(svcMthPrm.Name)} == null ? args.{writer.Ftl(svcMthPrm.Name)} : {defaultValueString})");
                                }
                            }
                            else
                            {
                                @params.Add($"args.{writer.Ftl(svcMthPrm.Name)}");
                            }
                        }
                    }

                    if (svcMth.ReturnType != null && svcMth.ReturnType != typeof(void))
                    {
                        writer.WriteLine($"response.@return = _{endpointName}.{svcMth.Name}({Environment.NewLine + String.Join("," + Environment.NewLine, @params.ToArray()) + Environment.NewLine});");
                    }
                    else
                    {
                        writer.WriteLine($"_{endpointName}.{svcMth.Name}({Environment.NewLine + String.Join("," + Environment.NewLine, @params.ToArray()) + Environment.NewLine});");
                    }

                    writer.WriteLine($"return response;");
                    writer.PopAndWriteLine("}");

                    writer.WriteLineAndPush("catch (Exception ex) {");
                    writer.WriteLine($"_Logger.LogCritical(ex, ex.Message);");
                    if (cfg.fillFaultPropertyOnException)
                    {
                        writer.WriteLine($"return new {svcMth.Name}Response {{ fault = {cfg.exceptionDisplay} }};");
                    }
                    else
                    {
                        writer.WriteLine($"return new {svcMth.Name}Response();");
                    }
                    writer.PopAndWriteLine("}");

                    writer.PopAndWriteLine("}"); //method
                }//foreach Method

                writer.WriteLine();
                writer.PopAndWriteLine("}"); //controller-class
            }//foreach Interface

            if (!String.IsNullOrWhiteSpace(cfg.outputNamespace))
            {
                writer.WriteLine();
                writer.WriteEndNamespace();
            }
        }