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("System"); nsImports.Add("System.Collections.Generic"); nsImports.Add("System.ComponentModel.DataAnnotations"); var wrapperContent = new StringBuilder(10000); 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(); //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); foreach (MethodInfo svcMth in svcInt.GetMethods()) { string svcMthDoc = XmlCommentAccessExtensions.GetDocumentation(svcMth, false); if (svcMth.ReturnType != null && svcMth.ReturnType != typeof(void)) { //directlyUsedModelTypes.Add(svcMth.ReturnType); if (!nsImports.Contains(svcMth.ReturnType.Namespace)) { nsImports.Add(svcMth.ReturnType.Namespace); } } string requestWrapperName = svcMth.Name + "Request"; string responseWrapperName = svcMth.Name + "Response"; StringBuilder requestWrapperContent = new StringBuilder(500); StringBuilder responseWrapperContent = new StringBuilder(500); requestWrapperContent.AppendLine(); requestWrapperContent.AppendLine("/// <summary>"); requestWrapperContent.AppendLine($"/// Contains arguments for calling '{svcMth.Name}'."); if (!String.IsNullOrWhiteSpace(svcMthDoc)) { requestWrapperContent.AppendLine($"/// Method: " + svcMthDoc.Replace("\n", "\n/// ")); } requestWrapperContent.AppendLine("/// </summary>"); requestWrapperContent.AppendLine("public class " + requestWrapperName + " {"); responseWrapperContent.AppendLine(); responseWrapperContent.AppendLine("/// <summary>"); responseWrapperContent.AppendLine($"/// Contains results from calling '{svcMth.Name}'."); if (!String.IsNullOrWhiteSpace(svcMthDoc)) { responseWrapperContent.AppendLine($"/// Method: " + svcMthDoc.Replace("\n", "\n/// ")); } responseWrapperContent.AppendLine("/// </summary>"); responseWrapperContent.AppendLine("public class " + responseWrapperName + " {"); foreach (ParameterInfo svcMthPrm in svcMth.GetParameters()) { string svcMthPrmDoc = XmlCommentAccessExtensions.GetDocumentation(svcMthPrm); if (String.IsNullOrWhiteSpace(svcMthPrmDoc)) { svcMthPrmDoc = XmlCommentAccessExtensions.GetDocumentation(svcMthPrm.ParameterType); } //directlyUsedModelTypes.Add(svcMthPrm.ParameterType); if (!nsImports.Contains(svcMthPrm.ParameterType.Namespace)) { nsImports.Add(svcMthPrm.ParameterType.Namespace); } string reqStr = "Required"; if (svcMthPrm.IsOptional) { reqStr = "Optional"; } //if (svcMthPrm.IsOptional) { // //paramSignature.Add($"{pt} {svcMthPrm.Name} = default({pt.Name})"); // if (pt.IsValueType) { // paramSignature.Add($"{pfx}{pt.Name}? {svcMthPrm.Name} = null"); // } // else { // paramSignature.Add($"{pfx}{pt.Name} {svcMthPrm.Name} = null"); // } //} //else { // paramSignature.Add($"{pfx}{pt.Name} {svcMthPrm.Name}"); //} //string accessModifier = "";//interfaces have no a.m. //if (modelTypeToGenerate.IsClass) { // accessModifier = "public "; //} //string pType = prop.PropertyType.Name; //if () String pType; String initializer = ""; bool nullable; if (svcMthPrm.IsOut) { pType = svcMthPrm.ParameterType.GetElementType().GetTypeNameSave(out nullable); } else { pType = svcMthPrm.ParameterType.GetTypeNameSave(out nullable); } if (nullable || (svcMthPrm.IsOptional && svcMthPrm.ParameterType.IsValueType)) { pType = pType + "?"; initializer = " = null;"; } if (!svcMthPrm.IsOut) { requestWrapperContent.AppendLine(); if (!String.IsNullOrWhiteSpace(svcMthPrmDoc)) { requestWrapperContent.AppendLine($" /// <summary> {reqStr} Argument for '{svcMth.Name}' ({pType}): {svcMthPrmDoc} </summary>"); } else { requestWrapperContent.AppendLine($" /// <summary> {reqStr} Argument for '{svcMth.Name}' ({pType}) </summary>"); } if (!svcMthPrm.IsOptional) { requestWrapperContent.AppendLine(" [Required]"); } requestWrapperContent.AppendLine(" public " + pType + " " + svcMthPrm.Name + " { get; set; }" + initializer); } if (svcMthPrm.IsOut) { responseWrapperContent.AppendLine(); if (!String.IsNullOrWhiteSpace(svcMthPrmDoc)) { responseWrapperContent.AppendLine($" /// <summary> Out-Argument of '{svcMth.Name}' ({pType}): {svcMthPrmDoc} </summary>"); } else { responseWrapperContent.AppendLine($" /// <summary> Out-Argument of '{svcMth.Name}' ({pType}) </summary>"); } if (!svcMthPrm.IsOptional) { responseWrapperContent.AppendLine(" [Required]"); } responseWrapperContent.AppendLine(" public " + pType + " " + svcMthPrm.Name + " { get; set; }" + initializer); } }//foreach Param if (cfg.generateFaultProperty) { responseWrapperContent.AppendLine(); responseWrapperContent.AppendLine($" /// <summary> This field contains error text equivalent to an Exception message! (note that only 'fault' XOR 'return' can have a value != null) </summary>"); responseWrapperContent.AppendLine(" public string fault { get; set; } = null;"); } requestWrapperContent.AppendLine(); requestWrapperContent.AppendLine("}"); if (svcMth.ReturnType != null && svcMth.ReturnType != typeof(void)) { responseWrapperContent.AppendLine(); string retTypeDoc = XmlCommentAccessExtensions.GetDocumentation(svcMth.ReturnType); if (!String.IsNullOrWhiteSpace(retTypeDoc)) { responseWrapperContent.AppendLine($" /// <summary> Return-Value of '{svcMth.Name}' ({svcMth.ReturnType.Name}): {retTypeDoc} </summary>"); } else { responseWrapperContent.AppendLine($" /// <summary> Return-Value of '{svcMth.Name}' ({svcMth.ReturnType.Name}) </summary>"); } if (!cfg.generateFaultProperty) { responseWrapperContent.AppendLine(" [Required]"); } responseWrapperContent.AppendLine(" public " + svcMth.ReturnType.Name + " @return { get; set; }"); } responseWrapperContent.AppendLine(); responseWrapperContent.AppendLine("}"); wrapperContent.Append(requestWrapperContent); wrapperContent.Append(responseWrapperContent); } //foreach Method } //foreach Interface //this can be done only here, because the nsImports will be extended during main-logic 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); } using (var sr = new StringReader(wrapperContent.ToString())) { string line = sr.ReadLine(); while (line != null) { writer.WriteLine(line); line = sr.ReadLine(); } } if (!String.IsNullOrWhiteSpace(cfg.outputNamespace)) { writer.WriteLine(); writer.WriteEndNamespace(); } }
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(); } }
public void Generate(CodeWriterBase writer, Cfg cfg) { if (writer.GetType() != typeof(WriterForCS)) { throw new Exception("For the selected template is currenty only language 'C#' supported!"); } var nsImports = new List <string>(); nsImports.Add("System"); nsImports.Add("System.Collections.Generic"); if (cfg.generateNavigationAnnotationsForLocalModels) { nsImports.Add("System.ComponentModel.DataAnnotations"); //+ extended by the "EntityAnnoations" Nuget Package! } else if (cfg.generateDataAnnotationsForLocalModels) { nsImports.Add("System.ComponentModel.DataAnnotations"); } var modelContent = new StringBuilder(10000); 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("\\*", ".*?") + ")$"; for (int i = 0; i < cfg.modelTypeNameIncludePatterns.Length; i++) { cfg.modelTypeNameIncludePatterns[i] = "^(" + Regex.Escape(cfg.modelTypeNameIncludePatterns[i]).Replace("\\*", ".*?") + ")$"; } svcInterfaces = svcInterfaces.Where((Type i) => Regex.IsMatch(i.FullName, cfg.interfaceTypeNamePattern)).ToArray(); //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); foreach (MethodInfo svcMth in svcInt.GetMethods()) { string svcMthDoc = XmlCommentAccessExtensions.GetDocumentation(svcMth, false); if (svcMth.ReturnType != null && svcMth.ReturnType != typeof(void)) { directlyUsedModelTypes.Add(svcMth.ReturnType); if (!nsImports.Contains(svcMth.ReturnType.Namespace)) { nsImports.Add(svcMth.ReturnType.Namespace); } } foreach (ParameterInfo svcMthPrm in svcMth.GetParameters()) { string svcMthPrmDoc = XmlCommentAccessExtensions.GetDocumentation(svcMthPrm); if (String.IsNullOrWhiteSpace(svcMthPrmDoc)) { svcMthPrmDoc = XmlCommentAccessExtensions.GetDocumentation(svcMthPrm.ParameterType); } directlyUsedModelTypes.Add(svcMthPrm.ParameterType); if (!nsImports.Contains(svcMthPrm.ParameterType.Namespace)) { nsImports.Add(svcMthPrm.ParameterType.Namespace); } } //foreach Param } //foreach Method } //foreach Interface Action <List <Type>, Type> addRecursiveMethod = null; addRecursiveMethod = (collector, candidate) => { if (candidate.IsArray) { candidate = candidate.GetElementType(); } else if (candidate.IsGenericType) { var genBase = candidate.GetGenericTypeDefinition(); var genArg1 = candidate.GetGenericArguments()[0]; if (typeof(List <>).MakeGenericType(genArg1).IsAssignableFrom(candidate)) { candidate = genArg1; } else if (typeof(Collection <>).MakeGenericType(genArg1).IsAssignableFrom(candidate)) { candidate = genArg1; } if (genBase == typeof(Nullable <>)) { candidate = genArg1; } } if (!collector.Contains(candidate)) { bool match = false; for (int i = 0; i < cfg.modelTypeNameIncludePatterns.Length; i++) { if (Regex.IsMatch(candidate.FullName, cfg.modelTypeNameIncludePatterns[i])) { match = true; break; } } if (match) { collector.Add(candidate); if (candidate.BaseType != null) { addRecursiveMethod.Invoke(collector, candidate.BaseType); } foreach (PropertyInfo p in candidate.GetProperties()) { addRecursiveMethod.Invoke(collector, p.PropertyType); } } } }; var modelTypesToGenerate = new List <Type>(); foreach (Type canidate in directlyUsedModelTypes.Distinct()) { addRecursiveMethod.Invoke(modelTypesToGenerate, canidate); } foreach (Type modelTypeToGenerate in modelTypesToGenerate.OrderBy((m) => m.Name)) { string modelDoc = XmlCommentAccessExtensions.GetDocumentation(modelTypeToGenerate, true); modelContent.AppendLine(); if (!String.IsNullOrWhiteSpace(modelDoc)) { modelContent.AppendLine($"/// <summary>"); modelContent.AppendLine($"/// " + modelDoc.Replace("\n", "\n/// ")); modelContent.AppendLine($"/// </summary>"); } //TODO: Obsolete-Attributes on Class-Level (including comments) if (modelTypeToGenerate.IsClass) { modelContent.Append("public class " + modelTypeToGenerate.Name); } else { modelContent.Append("public interface " + modelTypeToGenerate.Name); } if (modelTypeToGenerate.BaseType != null) { modelContent.AppendLine(" {"); } else { modelContent.AppendLine(" : " + modelTypeToGenerate.BaseType.Name + " {"); } foreach (PropertyInfo prop in modelTypeToGenerate.GetProperties()) { string propDoc = XmlCommentAccessExtensions.GetDocumentation(prop, true); modelContent.AppendLine(); if (!String.IsNullOrWhiteSpace(propDoc)) { modelContent.AppendLine($" /// <summary>"); modelContent.AppendLine($" /// " + propDoc.Replace("\n", "\n /// ")); modelContent.AppendLine($" /// </summary>"); } var attribs = prop.GetCustomAttributes(); if (cfg.generateDataAnnotationsForLocalModels) { if (prop.GetCustomAttributes <RequiredAttribute>().Any()) { modelContent.AppendLine(" [Required]"); } ObsoleteAttribute oa = prop.GetCustomAttributes <ObsoleteAttribute>().FirstOrDefault(); if (oa != null) { modelContent.AppendLine(" [Obsolete(\"" + oa.Message + "\")]"); } MaxLengthAttribute mla = prop.GetCustomAttributes <MaxLengthAttribute>().FirstOrDefault(); if (mla != null) { modelContent.AppendLine(" [MaxLength(" + mla.Length.ToString() + ")]"); } } if (cfg.generateNavigationAnnotationsForLocalModels) { //here we use strings, because we dont want to have a reference to a nuget-pkg within this template if (attribs.Where((a) => a.GetType().Name == "FixedAfterCreationAttribute").Any()) { modelContent.AppendLine(" [FixedAfterCreation]"); } if (attribs.Where((a) => a.GetType().Name == "SystemInternalAttribute").Any()) { modelContent.AppendLine(" [SystemInternal]"); } if (attribs.Where((a) => a.GetType().Name == "LookupAttribute").Any()) { modelContent.AppendLine(" [Lookup]"); } if (attribs.Where((a) => a.GetType().Name == "RefererAttribute").Any()) { modelContent.AppendLine(" [Referer]"); } if (attribs.Where((a) => a.GetType().Name == "PrincipalAttribute").Any()) { modelContent.AppendLine(" [Principal]"); } if (attribs.Where((a) => a.GetType().Name == "DependentAttribute").Any()) { modelContent.AppendLine(" [Dependent]"); } } string accessModifier = "";//interfaces have no a.m. if (modelTypeToGenerate.IsClass) { accessModifier = "public "; } modelContent.AppendLine($" " + accessModifier + prop.PropertyType.Name + " " + prop.Name + " { get; set; }"); } modelContent.AppendLine(); modelContent.AppendLine("}"); modelContent.AppendLine(); } //this can be done only here, because the nsImports will be extended during main-logic 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); } using (var sr = new StringReader(modelContent.ToString())) { string line = sr.ReadLine(); while (line != null) { writer.WriteLine(line); line = sr.ReadLine(); } } if (!String.IsNullOrWhiteSpace(cfg.outputNamespace)) { writer.WriteEndNamespace(); } }
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(); } }