public static MethodTemplate AddMethod(this ClassTemplate classTemplate, string name, TypeTemplate type) { MethodTemplate methodTemplate = new MethodTemplate(classTemplate, name, type); classTemplate.Methods.Add(methodTemplate); return(methodTemplate); }
public virtual void Write(ICodeFragment fragment, IOutputCache output) { MethodTemplate template = (MethodTemplate)fragment; if (template.Generics != null && template.Generics.Any(x => x.DefaultType != null)) { throw new InvalidOperationException($"This language does not support default types for generic methods. {template.Class.Name}.{template.Name}"); } output.Add(template.Comment) .Add(template.Attributes) .Add(template.Visibility.ToString().ToLower()).Add(" ") .If(template.IsStatic).Add("static ").EndIf() .If(template.IsOverride).Add("override ").EndIf() .If(template.Type != null).Add(template.Type).Add(" ").EndIf() .Add(template.Name) .If(template.Generics != null && template.Generics.Count > 0).Add("<").Add(template.Generics, ", ").Add(">").EndIf() .Add("(") .If(template is ExtensionMethodTemplate).Add("this ").EndIf() .Add(template.Parameters.OrderBy(x => x.DefaultValue == null ? 0 : 1), ", ") .Add(")"); this.BeforeBlock(fragment, output); output.StartBlock() .Add(template.Code) .EndBlock(); }
public static ParameterTemplate AddParameter(this MethodTemplate methodTemplate, TypeTemplate type, string name, ICodeFragment defaultValue = null) { var parameter = new ParameterTemplate(type, name, defaultValue); methodTemplate.Parameters.Add(parameter); return(parameter); }
public CodeGenMethod Create(DecoratorMethodInformation factoryInformation) { IEnumerable <CodeGenGeneric> genericTypes = factoryInformation.GenericTypes?.Select( parameter => FactoryHelpers.GenerateMethodParameter(parameter, factoryInformation.TypeConstraints)); IEnumerable <string> parameters = factoryInformation.Parameters?.Select(parameter => $"{parameter.Type} {parameter.Name}"); MethodTemplate matchingTemplate = _SelectorFactory .Create(factoryInformation.Templates) .Select( factoryInformation.MethodName, factoryInformation.ReturnType, factoryInformation.Parameters?.Select(parameter => parameter.Type)?.ToArray(), factoryInformation.IsAsync); string body = matchingTemplate != null ? GenerateDecoratorMethodBodyFromCondition( factoryInformation.MethodName, factoryInformation.ReturnType, matchingTemplate, factoryInformation.Parameters) : GenerateUndecoratedMethodBody( factoryInformation.MethodName, factoryInformation.Parameters); return(new CodeGenMethod( factoryInformation.MethodName, factoryInformation.ReturnType, Scope.Public, MethodType.Normal, genericTypes, parameters, body, matchingTemplate?.Async ?? false)); }
public void OverrideMethod() { MethodTemplate template = new MethodTemplate(null, "test", Code.Type("type")).Override(); template.Code.AddLine(Code.Comment("Some code here")); MethodWriter writer = new MethodWriter(); writer.Write(template, this.output); Assert.AreEqual("public override type test()\r\n{\r\n // Some code here\r\n}", this.output.ToString()); }
public void ParameterMethod() { Assert.Inconclusive("Not implemented yet"); MethodTemplate template = new MethodTemplate(null, "test", Code.Type("type")); template.Parameters.Add(new ParameterTemplate(Code.Type("other"), "param")); template.Code.AddLine(Code.Comment("Some code here")); MethodWriter writer = new MethodWriter(); writer.Write(template, this.output); Assert.AreEqual("public type test(other param)\r\n{\r\n // Some code here\r\n}", this.output.ToString()); }
public virtual void Write(ICodeFragment fragment, IOutputCache output) { MethodTemplate template = (MethodTemplate)fragment; output.Add(template.Comment) .Add(template.Attributes) .If(template.Visibility != Visibility.None).Add(template.Visibility.ToString().ToLower()).Add(" ").EndIf() .If(template.IsStatic).Add("static ").EndIf() .If(template.IsOverride).Add("override ").EndIf() .Add(template.Name) .Add("(") .Add(template.Parameters.OrderBy(x => x.DefaultValue == null ? 0 : 1), ", ") .Add(")") .If(template.Type != null).Add(": ").Add(template.Type).EndIf() .StartBlock() .Add(template.Code) .EndBlock(); }
private string GenerateDecoratorMethodBodyFromCondition( string methodName, string returnType, MethodTemplate template, IEnumerable <MethodParameter> parameters) { IEnumerable <string> paramNameList = parameters?.Select(parameter => parameter.Name) ?? new string[0]; string invocation = $"_Decorated.{methodName}({string.Join(", ", paramNameList)})"; string body = template.Body.Clone() as string; if (returnType == "void" && template.MatchCondition.ReturnTypeRule == ReturnTypeRule.Any) { body = VoidReturnMethodInvokeRegex.Replace(body, invocation); } else { body = MethodInvokeRegex.Replace(body, invocation); } return(FactoryHelpers.CleanBody(body)); }
private void AddPlaceHolderStatements(MethodTemplate template, MethodDeclarationSyntax node) { foreach (var item in node.DescendantNodes().OfType <InvocationExpressionSyntax>()) { switch (item.Expression.ToString()) { case nameof(WrapperTemplate.Body): template.OriginalBodies.Add(item.Parent); break; case nameof(WrapperTemplate.Default): template.DefaultReturns.Add(item.Parent); break; } } foreach (var item in node.DescendantNodes().OfType <ObjectCreationExpressionSyntax>()) { if (item.Type.ToString() == _metadataType.Name) { template.MetaData = item; break; } } }
public static ExecuteMethodTemplate Method(this ChainedCodeFragment template, MethodTemplate method, IEnumerable <ICodeFragment> parameters) { return(Method(template, method.Name, parameters)); }
public static ExecuteMethodTemplate Method(this ChainedCodeFragment template, MethodTemplate method, params ICodeFragment[] parameters) { return(Method(template, method.Name, parameters)); }
public static MethodTemplate FormatName(this MethodTemplate methodTemplate, IOptions options, bool force = false) { methodTemplate.Name = Formatter.FormatMethod(methodTemplate.Name, options, force); return(methodTemplate); }
public static MethodTemplate WithCode(this MethodTemplate methodTemplate, ICodeFragment code) { methodTemplate.Code.Fragments.Add(code); return(methodTemplate); }
public static MethodTemplate Internal(this MethodTemplate methodTemplate) { methodTemplate.Visibility = Visibility.Internal; return(methodTemplate); }
public static MethodTemplate Protected(this MethodTemplate methodTemplate) { methodTemplate.Visibility = Visibility.Protected; return(methodTemplate); }
public static MethodTemplate WithGeneric(this MethodTemplate methodTemplate, string alias, TypeTemplate defaultType = null) { methodTemplate.Generics.Add(new MethodGenericTemplate(alias, defaultType)); return(methodTemplate); }
public static MethodTemplate FormatName(this MethodTemplate methodTemplate, ILanguage language, bool formatNames) { methodTemplate.Name = Formatter.FormatMethod(methodTemplate.Name, language, formatNames); return(methodTemplate); }
public static MethodTemplate Override(this MethodTemplate methodTemplate, bool value = true) { methodTemplate.IsOverride = value; return(methodTemplate); }
public static MethodTemplate Static(this MethodTemplate methodTemplate, bool value = true) { methodTemplate.IsStatic = value; return(methodTemplate); }
public static MethodTemplate Private(this MethodTemplate methodTemplate) { methodTemplate.Visibility = Visibility.Private; return(methodTemplate); }
public static MethodTemplate FormatName(this MethodTemplate methodTemplate, IConfiguration configuration) { methodTemplate.Name = Formatter.FormatMethod(methodTemplate.Name, configuration); return(methodTemplate); }
protected virtual ClassTemplate WriteClass(EntityFrameworkWriteConfiguration configuration, List <ITransferObject> transferObjects, List <FileTemplate> files) { ClassTemplate dataContext = files.AddFile(configuration.RelativePath, configuration.AddHeader) .AddNamespace(configuration.Namespace) .AddClass("DataContext", Code.Type("DbContext")); if (configuration.IsCore) { dataContext.WithUsing("Microsoft.EntityFrameworkCore"); } else { dataContext.WithUsing("System.Data.Entity"); } configuration.Usings.ForEach(x => dataContext.AddUsing(x)); PropertyTemplate defaultConnectionProperty = dataContext.AddProperty("DefaultConnection", Code.Type("string")).Static().WithDefaultValue(Code.String("name=DataContext")); foreach (EntityTransferObject entity in transferObjects.OfType <EntityTransferObject>()) { dataContext.AddProperty(entity.Name, Code.Generic("DbSet", entity.Model.ToTemplate())) .FormatName(configuration) .Virtual(); } dataContext.AddConstructor() .WithThisConstructor(Code.Null()); ConstructorTemplate constructor = dataContext.AddConstructor(); ParameterTemplate connectionString = constructor.AddParameter(Code.Type("string"), "connectionString"); if (configuration.IsCore) { constructor.WithBaseConstructor(Code.Static(Code.Type("SqlServerDbContextOptionsExtensions")).Method("UseSqlServer", Code.New(Code.Type("DbContextOptionsBuilder")), Code.NullCoalescing(Code.Local(connectionString), Code.Local(defaultConnectionProperty))).Property("Options")) .Code.AddLine(Code.This().Property("Database").Method("SetCommandTimeout", Code.Number(configuration.DataContext.CommandTimeout)).Close()); } else { constructor.WithBaseConstructor(Code.NullCoalescing(Code.Local("connectionString"), Code.Local(defaultConnectionProperty))) .Code.AddLine(Code.This().Property("Database").Property("CommandTimeout").Assign(Code.Number(configuration.DataContext.CommandTimeout)).Close()); } MethodTemplate createMethod = dataContext.AddMethod("OnModelCreating", Code.Void()).Protected().Override(); ParameterTemplate modelBuilder = createMethod.AddParameter(Code.Type(configuration.IsCore ? "ModelBuilder" : "DbModelBuilder"), "modelBuilder"); if (!configuration.IsCore) { createMethod.Code.AddLine(Code.Local(modelBuilder).Property("Configurations").Method("AddFromAssembly", Code.This().Method("GetType").Property("Assembly")).Close()); } foreach (EntityTransferObject entity in transferObjects.OfType <EntityTransferObject>()) { createMethod.Code.AddLine(Code.Local(modelBuilder).GenericMethod("Entity", entity.Model.ToTemplate()).BreakLine() .Method("ToTable", Code.String(entity.Table), Code.String(entity.Schema)).BreakLine() .Method("HasKey", Code.Lambda("x", Code.Csharp("new { " + string.Join(", ", entity.Keys.Select(key => $"x.{key.Name}")) + " }"))).Close()); } foreach (StoredProcedureTransferObject storedProcedure in transferObjects.OfType <StoredProcedureTransferObject>()) { dataContext.AddMethod(storedProcedure.Name, storedProcedure.ReturnType.ToTemplate()) .Code.AddLine(Code.This().Property("Database").Method("ExecuteSqlCommand", Code.String($"exec {storedProcedure.Schema}.{storedProcedure.Name}")).Close()); } return(dataContext); }
public virtual void Write(AspDotNetWriteConfiguration configuration, List <ITransferObject> transferObjects, List <FileTemplate> files) { if (!configuration.Language.IsCsharp()) { throw new InvalidOperationException($"Can not generate ASP.net Controller for language {configuration.Language?.Name ?? "Empty"}. Only Csharp is currently implemented"); } foreach (AspDotNetWriteEntityControllerConfiguration controllerConfiguration in configuration.Controllers) { EntityTransferObject entity = transferObjects.OfType <EntityTransferObject>().FirstOrDefault(x => x.Name == controllerConfiguration.Entity) .AssertIsNotNull(nameof(controllerConfiguration.Entity), $"Entity {controllerConfiguration.Entity} not found. Ensure it is read before."); string nameSpace = (controllerConfiguration.Namespace ?? configuration.Namespace).AssertIsNotNull(nameof(configuration.Namespace), "asp writer requires a namespace"); ClassTemplate controller = files.AddFile(configuration.RelativePath, configuration.AddHeader) .AddNamespace(nameSpace) .AddClass(controllerConfiguration.Name ?? entity.Name + "Controller", Code.Type(configuration.Template.ControllerBase)) .FormatName(configuration) .WithAttribute("Route", Code.String(controllerConfiguration.Route ?? "[controller]")); controller.Usings.AddRange(configuration.Template.Usings); TypeTemplate modelType = entity.Model.ToTemplate(); configuration.Usings.ForEach(x => controller.AddUsing(x)); controllerConfiguration.Usings.ForEach(x => controller.AddUsing(x)); FieldTemplate repositoryField = controller.AddField("repository", Code.Type(entity.Name + "Repository")).Readonly(); controller.AddConstructor().Code.AddLine(Code.This().Field(repositoryField).Assign(Code.New(repositoryField.Type)).Close()); if (controllerConfiguration.Get != null) { controller.AddUsing("System.Linq"); MethodTemplate method = controller.AddMethod("Get", Code.Generic("IEnumerable", modelType)); if (configuration.Template.UseAttributes) { method.WithAttribute("HttpGet", Code.String(controllerConfiguration.Get.Name ?? "[action]")); } DeclareTemplate queryable = Code.Declare(Code.Generic("IQueryable", modelType), "queryable", Code.This().Field(repositoryField).Method("Get")); method.Code.AddLine(queryable); foreach (PropertyTransferObject property in entity.Model.Properties) { ParameterTemplate parameter = method.AddParameter(property.Type.ToTemplate(), property.Name, Code.Local("default")).FormatName(configuration); method.Code.AddLine(Code.If(Code.Local(parameter).NotEquals().Local("default"), x => x.Code.AddLine(Code.Local(queryable).Assign(Code.Local(queryable).Method("Where", Code.Lambda("x", Code.Local("x").Property(property.Name).Equals().Local(parameter)))).Close()))); } method.Code.AddLine(Code.Return(Code.Local(queryable))); } if (controllerConfiguration.Post != null) { MethodTemplate method = controller.AddMethod("Post", Code.Void()); if (configuration.Template.UseAttributes) { method.WithAttribute("HttpPost", Code.String(controllerConfiguration.Post.Name ?? "[action]")); } ParameterTemplate parameter = method.AddParameter(modelType, "entity") .WithAttribute("FromBody"); method.Code.AddLine(Code.This().Field(repositoryField).Method("Add", Code.Local(parameter)).Close()); } if (controllerConfiguration.Patch != null) { MethodTemplate method = controller.AddMethod("Patch", Code.Void()); if (configuration.Template.UseAttributes) { method.WithAttribute("HttpPatch", Code.String(controllerConfiguration.Patch.Name ?? "[action]")); } ParameterTemplate parameter = method.AddParameter(modelType, "entity") .WithAttribute("FromBody"); method.Code.AddLine(Code.This().Field(repositoryField).Method("Update", Code.Local(parameter)).Close()); } if (controllerConfiguration.Put != null) { MethodTemplate method = controller.AddMethod("Put", Code.Void()); if (configuration.Template.UseAttributes) { method.WithAttribute("HttpPut", Code.String(controllerConfiguration.Put.Name ?? "[action]")); } ParameterTemplate parameter = method.AddParameter(modelType, "entity") .WithAttribute("FromBody"); method.Code.AddLine(Code.This().Field(repositoryField).Method("Update", Code.Local(parameter)).Close()); } if (controllerConfiguration.Delete != null) { MethodTemplate method = controller.AddMethod("Delete", Code.Void()); if (configuration.Template.UseAttributes) { method.WithAttribute("HttpDelete", Code.String(controllerConfiguration.Delete.Name ?? "[action]")); } List <ParameterTemplate> parameters = new List <ParameterTemplate>(); foreach (EntityKeyTransferObject key in entity.Keys) { PropertyTransferObject property = entity.Model.Properties.First(x => x.Name.Equals(key.Name, StringComparison.InvariantCultureIgnoreCase)); parameters.Add(method.AddParameter(property.Type.ToTemplate(), property.Name) .FormatName(configuration)); } method.Code.AddLine(Code.This().Field(repositoryField).Method("Delete", parameters.Select(x => Code.Local(x))).Close()); } } }
public static MethodTemplate WithComment(this MethodTemplate methodTemplate, string description) { methodTemplate.Comment = new CommentTemplate(description, CommentType.Summary); return(methodTemplate); }
public static MethodTemplate WithParameter(this MethodTemplate methodTemplate, ParameterTemplate parameter) { methodTemplate.Parameters.Add(parameter); return(methodTemplate); }
public virtual void Write(AspDotNetWriteConfiguration configuration, List <FileTemplate> files) { Logger.Trace("Generate generator controller for ASP.net..."); if (!configuration.Language.IsCsharp()) { throw new InvalidOperationException($"Can not generate ASP.net Controller for language {configuration.Language?.Name ?? "Empty"}. Only Csharp is currently implemented"); } if (configuration.Standalone) { throw new InvalidOperationException("Can not generate Generator.Controller with KY.Generator.CLI.Standalone use KY.Generator.CLI instead"); } string nameSpace = (configuration.GeneratorController.Namespace ?? configuration.Namespace).AssertIsNotNull(nameof(configuration.Namespace), "asp writer requires a namespace"); ClassTemplate classTemplate = files.AddFile(configuration.GeneratorController.RelativePath ?? configuration.RelativePath, configuration.AddHeader) .AddNamespace(nameSpace) .AddClass("GeneratorController", Code.Type(configuration.Template.ControllerBase)) .WithUsing("System") .WithUsing("System.Linq") .WithUsing("KY.Generator") .WithUsing("KY.Generator.Output"); classTemplate.Usings.AddRange(configuration.Template.Usings); if (configuration.Template.UseOwnCache) { GenericTypeTemplate type = Code.Generic("Dictionary", Code.Type("string"), Code.Type("MemoryOutput")); classTemplate.AddField("cache", type) .FormatName(configuration) .Static() .Readonly() .DefaultValue = Code.New(type); } MethodTemplate createMethod = classTemplate.AddMethod("Create", Code.Type("string")) .FormatName(configuration) .WithParameter(Code.Type("string"), "configuration"); if (!configuration.Template.ValidateInput) { createMethod.WithAttribute("ValidateInput", Code.Local("false")); } MethodTemplate commandMethod = classTemplate.AddMethod("Command", Code.Type("string")) .FormatName(configuration) .WithParameter(Code.Type("string"), "command"); MultilineCodeFragment createCode = createMethod.Code; createCode.AddLine(Code.Declare(Code.Type("string"), "id", Code.Local("Guid").Method("NewGuid").Method("ToString"))) .AddLine(Code.Declare(Code.Type("MemoryOutput"), "output", Code.New(Code.Type("MemoryOutput")))) .AddLine(Code.Declare(Code.Type("Generator"), "generator", Code.New(Code.Type("Generator")))) .AddLine(Code.Local("generator").Method("SetOutput", Code.Local("output")).Close()); MultilineCodeFragment commandCode = commandMethod.Code; commandCode.AddLine(Code.Declare(Code.Type("string"), "id", Code.Local("Guid").Method("NewGuid").Method("ToString"))) .AddLine(Code.Declare(Code.Type("MemoryOutput"), "output", Code.New(Code.Type("MemoryOutput")))) .AddLine(Code.Declare(Code.Type("Generator"), "generator", Code.New(Code.Type("Generator")))) .AddLine(Code.Local("generator").Method("SetOutput", Code.Local("output")).Close()); foreach (string ns in configuration.GeneratorController.Usings) { classTemplate.AddUsing(ns); } foreach (string moduleType in configuration.GeneratorController.PreloadModules) { createCode.AddLine(Code.Local("generator").GenericMethod("PreloadModule", Code.Type(moduleType)).Close()); commandCode.AddLine(Code.Local("generator").GenericMethod("PreloadModule", Code.Type(moduleType)).Close()); } foreach (AspDotNetControllerConfigureModule configure in configuration.GeneratorController.Configures) { createCode.AddLine(Code.Local("generator").Method(configure.Module, Code.Lambda("x", Code.Csharp("x." + configure.Action)))); commandCode.AddLine(Code.Local("generator").Method(configure.Module, Code.Lambda("x", Code.Csharp("x." + configure.Action)))); } createCode.AddLine(Code.Local("generator").Method("ParseConfiguration", Code.Local("configuration")).Close()) .AddLine(Code.Local("generator").Method("Run").Close()) .AddBlankLine(); commandCode.AddLine(Code.Local("generator").Method("ParseCommand", Code.Local("command")).Close()) .AddLine(Code.Local("generator").Method("Run").Close()) .AddBlankLine(); if (configuration.Template.UseOwnCache) { createCode.AddLine(Code.Local("cache").Index(Code.Local("id")).Assign(Code.Local("output")).Close()); commandCode.AddLine(Code.Local("cache").Index(Code.Local("id")).Assign(Code.Local("output")).Close()); } else { createCode.AddLine(Code.Static(Code.Type("HttpContext")).Property("Current").Property("Cache").Index(Code.Local("id")).Assign(Code.Local("output")).Close()); commandCode.AddLine(Code.Static(Code.Type("HttpContext")).Property("Current").Property("Cache").Index(Code.Local("id")).Assign(Code.Local("output")).Close()); } createCode.AddLine(Code.Return(Code.Local("id"))); commandCode.AddLine(Code.Return(Code.Local("id"))); ChainedCodeFragment getFromCacheForFilesFragment = configuration.Template.UseOwnCache ? (ChainedCodeFragment)Code.Local("cache") : Code.Static(Code.Type("HttpContext")).Property("Current").Property("Cache"); MethodTemplate getFilesMethod = classTemplate.AddMethod("GetFiles", Code.Type("string")) .FormatName(configuration) .WithParameter(Code.Type("string"), "id"); getFilesMethod.Code.AddLine(Code.If(Code.Local("id").Equals().Null(), x => x.Code.AddLine(Code.Return(Code.Null())))) .AddLine(Code.Declare(Code.Type("MemoryOutput"), "output", getFromCacheForFilesFragment.Index(Code.Local("id")).As(Code.Type("MemoryOutput")))) .AddLine(Code.Return(Code.InlineIf(Code.Local("output").Equals().Null(), Code.Null(), Code.Local("string").Method("Join", Code.Local("Environment").Property("NewLine"), Code.Local("output").Property("Files").Method("Select", Code.Lambda("x", Code.Local("x").Property("Key"))))))); ChainedCodeFragment getFromCacheForFileFragment = configuration.Template.UseOwnCache ? (ChainedCodeFragment)Code.Local("cache") : Code.Static(Code.Type("HttpContext")).Property("Current").Property("Cache"); MethodTemplate getFileMethod = classTemplate.AddMethod("GetFile", Code.Type("string")) .FormatName(configuration) .WithParameter(Code.Type("string"), "id") .WithParameter(Code.Type("string"), "path"); getFileMethod.Code.AddLine(Code.If(Code.Local("id").Equals().Null(), x => x.Code.AddLine(Code.Return(Code.Null())))) .AddLine(Code.Declare(Code.Type("MemoryOutput"), "output", getFromCacheForFileFragment.Index(Code.Local("id")).As(Code.Type("MemoryOutput")))) .AddLine(Code.Return(Code.InlineIf(Code.Local("output").Equals().Null().Or().Not().Local("output").Property("Files").Method("ContainsKey", Code.Local("path")), Code.Null(), Code.Local("output").Property("Files").Index(Code.Local("path"))))); MethodTemplate availableMethod = classTemplate.AddMethod("Available", Code.Type("bool")) .FormatName(configuration); availableMethod.Code.AddLine(Code.Return(Code.Local("true"))); if (configuration.Template.UseAttributes) { classTemplate.WithUsing("Microsoft.AspNetCore.Mvc") .WithAttribute("Route", Code.String("[controller]")) .WithAttribute("Route", Code.String("api/v1/[controller]")); createMethod.WithAttribute("HttpPost", Code.String("[action]")); commandMethod.WithAttribute("HttpPost", Code.String("[action]")); getFilesMethod.WithAttribute("HttpPost", Code.String("[action]")); getFileMethod.WithAttribute("HttpPost", Code.String("[action]")); availableMethod.WithAttribute("HttpGet", Code.String("[action]")); } }
public static MethodTemplate WithParameter(this MethodTemplate methodTemplate, TypeTemplate type, string name, ICodeFragment defaultValue = null) { methodTemplate.AddParameter(type, name, defaultValue); return(methodTemplate); }
public static MethodTemplate WithParameters(this MethodTemplate methodTemplate, IEnumerable <ParameterTemplate> parameters) { methodTemplate.Parameters.AddRange(parameters); return(methodTemplate); }
public virtual void Write(ICodeFragment fragment, IOutputCache output) { BaseLanguage language = this.options.Language.CastTo <BaseLanguage>(); ClassTemplate template = (ClassTemplate)fragment; output.Add(template.Comment); output.Add(template.Attributes); output.Add(language.ClassScope).Add(" "); if (template.IsAbstract && language.HasAbstractClasses && !template.IsInterface) { output.Add("abstract "); } if (template.IsStatic && language.HasStaticClasses) { output.Add("static "); } else if (!string.IsNullOrEmpty(language.PartialKeyword)) { output.Add(language.PartialKeyword).Add(" "); } if (template.IsInterface) { output.Add("interface "); } else { output.Add("class "); } output.Add(template.Name); if (template.Generics.Count > 0) { output.Add("<").Add(template.Generics.Select(x => Code.Instance.Type(x.Name)), ", ").Add(">"); } template.BasedOn.OrderBy(x => x.ToType().IsInterface).ForEach(x => output.Add(x)); output.Add(template.Generics.Select(x => x.ToConstraints()).Where(x => x.Types.Count > 0)); output.StartBlock(); if (template.IsInterface) { template.Fields.ForEach(x => x.Visibility = Visibility.None); template.Properties.ForEach(x => x.Visibility = Visibility.None); } bool isFirst = true; if (template.Classes.Count > 0) { output.Add(template.Classes); isFirst = false; } if (template.Fields.Count > 0) { output.If(!isFirst).BreakLine().EndIf(); output.Add(template.Fields); isFirst = false; } if (template.Properties.Count > 0) { output.If(!isFirst).BreakLine().EndIf(); output.Add(template.Properties); isFirst = false; } if (template.Code != null) { output.If(!isFirst).BreakLine().EndIf(); output.Add(template.Code); isFirst = false; } if (template.Methods.Count > 0) { output.If(!isFirst).BreakLine().EndIf(); MethodTemplate last = template.Methods.Last(); foreach (MethodTemplate method in template.Methods) { output.Add(method); if (method != last) { output.BreakLine(); } } } if (this.options.Formatting.CollapseEmptyClasses && output.LastFragments.First().Equals(template)) { output.UnBreakLine(); output.Add(this.options.Formatting.CollapsedClassesSpacer, true); } output.EndBlock(); }
public virtual void Write(AngularWriteConfiguration configuration, List <ITransferObject> transferObjects, List <FileTemplate> files) { Logger.Trace("Generate angular service for ASP.net controller..."); if (!configuration.Language.IsTypeScript()) { throw new InvalidOperationException($"Can not generate service for ASP.net Controller for language {configuration.Language?.Name ?? "Empty"}"); } string httpClient = configuration.Service.HttpClient?.Name ?? "HttpClient"; string httpClientImport = configuration.Service.HttpClient?.Import ?? "@angular/common/http"; foreach (HttpServiceTransferObject controller in transferObjects.OfType <HttpServiceTransferObject>()) { Dictionary <HttpServiceActionParameterTransferObject, ParameterTemplate> mapping = new Dictionary <HttpServiceActionParameterTransferObject, ParameterTemplate>(); string controllerName = controller.Name.TrimEnd("Controller"); ClassTemplate classTemplate = files.AddFile(configuration.Service.RelativePath, configuration.AddHeader) .AddNamespace(string.Empty) .AddClass(configuration.Service.Name ?? controllerName + "Service") .FormatName(configuration) .WithUsing(httpClient, httpClientImport) .WithUsing("Injectable", "@angular/core") .WithUsing("Observable", "rxjs") .WithUsing("Subject", "rxjs") .WithAttribute("Injectable", Code.AnonymousObject().WithProperty("providedIn", Code.String("root"))); FieldTemplate httpField = classTemplate.AddField("http", Code.Type(httpClient)).Readonly().FormatName(configuration); FieldTemplate serviceUrlField = classTemplate.AddField("serviceUrl", Code.Type("string")).Public().FormatName(configuration).Default(Code.String(string.Empty)); classTemplate.AddConstructor().WithParameter(Code.Type(httpClient), "http") .WithCode(Code.This().Field(httpField).Assign(Code.Local("http")).Close()); string relativeModelPath = FileSystem.RelativeTo(configuration.Model?.RelativePath ?? ".", configuration.Service.RelativePath); foreach (HttpServiceActionTransferObject action in controller.Actions) { ICodeFragment errorCode = Code.Lambda("error", Code.Local("subject").Method("error", Code.Local("error"))); this.MapType(controller.Language, configuration.Language, action.ReturnType); TypeTemplate returnType = action.ReturnType.ToTemplate(); this.AddUsing(action.ReturnType, classTemplate, configuration, relativeModelPath); MethodTemplate methodTemplate = classTemplate.AddMethod(action.Name, Code.Generic("Observable", returnType)) .FormatName(configuration); foreach (HttpServiceActionParameterTransferObject parameter in action.Parameters) { this.MapType(controller.Language, configuration.Language, parameter.Type); this.AddUsing(parameter.Type, classTemplate, configuration, relativeModelPath); ParameterTemplate parameterTemplate = methodTemplate.AddParameter(parameter.Type.ToTemplate(), parameter.Name).FormatName(configuration); mapping.Add(parameter, parameterTemplate); } methodTemplate.AddParameter(Code.Type("{}"), "httpOptions?"); TypeTemplate subjectType = Code.Generic("Subject", returnType); methodTemplate.WithCode(Code.Declare(subjectType, "subject", Code.New(subjectType))); string uri = ("/" + (controller.Route?.Replace("[controller]", controllerName.ToLower()).TrimEnd('/') ?? controllerName) + "/" + action.Route?.Replace("[action]", action.Name.ToLower())).TrimEnd('/'); List <HttpServiceActionParameterTransferObject> inlineParameters = action.Parameters.Where(x => !x.FromBody && x.Inline).OrderBy(x => x.InlineIndex).ToList(); List <HttpServiceActionParameterTransferObject> urlParameters = action.Parameters.Where(x => !x.FromBody && !x.Inline && x.AppendName).ToList(); List <HttpServiceActionParameterTransferObject> urlDirectParameters = action.Parameters.Where(x => !x.FromBody && !x.Inline && !x.AppendName).ToList(); uri = urlParameters.Count > 0 ? $"{uri}?{urlParameters.First().Name}=" : urlDirectParameters.Count > 0 ? $"{uri}?" : uri; MultilineCodeFragment code = Code.Multiline(); DeclareTemplate declareTemplate = null; bool hasReturnType = returnType.Name != "void"; bool isPrimitive = this.IsPrimitive(returnType); if (returnType.Name == "Array") { TypeTemplate type = ((GenericTypeTemplate)returnType).Types[0]; declareTemplate = Code.Declare(returnType, "list", Code.TypeScript("[]")).Constant(); code.AddLine(declareTemplate) .AddLine(Code.TypeScript("for (const entry of <[]>result)").StartBlock()) .AddLine(Code.Local(declareTemplate).Method("push", isPrimitive ? (ICodeFragment)Code.Cast(type, Code.Local("entry")) : Code.New(type, Code.Local("entry"))).Close()) .AddLine(Code.TypeScript("").EndBlock()); } else if (hasReturnType) { declareTemplate = Code.Declare(returnType, "model", isPrimitive ? (ICodeFragment)Code.Cast(returnType, Code.Local("result")) : Code.New(returnType, Code.Local("result"))).Constant(); code.AddLine(declareTemplate); } code.AddLine(Code.Local("subject").Method("next").WithParameter(declareTemplate.ToLocal()).Close()) .AddLine(Code.Local("subject").Method("complete").Close()); ChainedCodeFragment parameterUrl = Code.This().Field(serviceUrlField); if (inlineParameters.Count == 0) { parameterUrl = parameterUrl.Append(Code.String(uri)); } foreach (HttpServiceActionParameterTransferObject parameter in inlineParameters) { string[] chunks = uri.Split(new [] { $"{{{parameter.Name}}}" }, StringSplitOptions.RemoveEmptyEntries); parameterUrl = parameterUrl.Append(Code.String(chunks[0])).Append(Code.Local(parameter.Name)); uri = chunks.Length == 1 ? string.Empty : chunks[1]; } bool isFirst = true; foreach (HttpServiceActionParameterTransferObject parameter in urlDirectParameters) { if (isFirst) { isFirst = false; parameterUrl = parameterUrl.Append(Code.Local(parameter.Name)); } else { parameterUrl = parameterUrl.Append(Code.String("&")).Append(Code.Local(parameter.Name)); } } foreach (HttpServiceActionParameterTransferObject parameter in urlParameters) { if (isFirst) { isFirst = false; parameterUrl = parameterUrl.Append(Code.Local(mapping[parameter])); } else { parameterUrl = parameterUrl.Append(Code.String($"&{parameter.Name}=")).Append(Code.Local(mapping[parameter])); } } methodTemplate.WithCode( Code.This() .Field(httpField) .Method(action.Type.ToString().ToLowerInvariant(), parameterUrl, action.RequireBodyParameter ? Code.Local(action.Parameters.Single(x => x.FromBody).Name) : null, Code.Local("httpOptions") ) .Method("subscribe", Code.Lambda(hasReturnType ? "result" : null, code), errorCode).Close() ); methodTemplate.WithCode(Code.Return(Code.Local("subject"))); } } }