using System.Text; using NodePipeline.Engine.CodeGeneration.Abstractions; namespace NodePipeline.Engine.DependencyInjection.CodeGeneration; internal static class DiExtensionsGenerator { public static string Generate(NodeModelBuilder.NodesModel model) { var sb = new StringBuilder(); sb.AppendLine("using System.Globalization;"); sb.AppendLine("using Microsoft.Extensions.DependencyInjection;"); sb.AppendLine("using NodePipeline.Abstractions;"); sb.AppendLine("using NodePipeline.Abstractions.Interfaces;"); sb.AppendLine("using NodePipeline.Abstractions.Interfaces.Nodes;"); sb.AppendLine("using NodePipeline.Abstractions.Interfaces.Validation;"); sb.AppendLine("using NodePipeline.Engine.Abstractions;"); sb.AppendLine("using NodePipeline.Engine.Execution;"); sb.AppendLine("using NodePipeline.Engine.Generated;"); sb.AppendLine(); sb.AppendLine("#nullable enable"); sb.AppendLine(); sb.AppendLine("namespace NodePipeline.Engine.DependencyInjection;"); sb.AppendLine(); sb.AppendLine("public static class PipelineServiceCollectionExtensions"); sb.AppendLine("{"); sb.AppendLine(BuildAddPipelineMethod()); sb.AppendLine(); sb.AppendLine(BuildAddNodeFactoryMethod()); sb.AppendLine(); sb.AppendLine(BuildAddNodeValidatorMethod()); sb.AppendLine(); sb.AppendLine("}"); sb.AppendLine(); sb.AppendLine(BuildPipelineProviderExtensionsClass()); sb.AppendLine(); sb.AppendLine(BuildPipelineNodeExtensionsClass()); sb.AppendLine(); sb.AppendLine(BuildPipelineNodeValidatorExtensionsClass()); sb.AppendLine(); sb.AppendLine(BuildPipelineFieldValidatorExtensionsClass()); sb.AppendLine("#nullable restore"); return sb.ToString(); } private static string BuildAddPipelineMethod() { var sb = new StringBuilder(); sb.AppendLine(" public static IServiceCollection AddPipeline(this IServiceCollection services)"); sb.AppendLine(" {"); sb.AppendLine(" services.AddSingleton();"); sb.AppendLine(); sb.AppendLine(" AddNodeFactory(services);"); sb.AppendLine(" AddNodeValidator(services);"); sb.AppendLine(); sb.AppendLine(" services.AddSingleton(sp => new PipelineRegistry(CultureInfo.CurrentCulture));"); sb.AppendLine(" return services;"); sb.AppendLine(" }"); return sb.ToString(); } private static string BuildAddNodeFactoryMethod() { var sb = new StringBuilder(); sb.AppendLine(" private static void AddNodeFactory(IServiceCollection services)"); sb.AppendLine(" {"); sb.AppendLine(" services.AddScoped();"); sb.AppendLine(" services.AddScoped(sp =>"); sb.AppendLine(" {"); sb.AppendLine(" var inner = sp.GetRequiredService();"); sb.AppendLine( " return new DiNodeFactory(sp, inner, sp.GetService());"); sb.AppendLine(" });"); sb.AppendLine(" }"); return sb.ToString(); } private static string BuildAddNodeValidatorMethod() { var sb = new StringBuilder(); sb.AppendLine(" private static void AddNodeValidator(IServiceCollection services)"); sb.AppendLine(" {"); sb.AppendLine(" services.AddScoped();"); sb.AppendLine(" services.AddScoped(sp =>"); sb.AppendLine(" {"); sb.AppendLine(" var inner = sp.GetRequiredService();"); sb.AppendLine( " return new DiNodeValidator(sp, inner, sp.GetService());"); sb.AppendLine(" });"); sb.AppendLine(" }"); return sb.ToString(); } //classes private static string BuildPipelineProviderExtensionsClass() { var sb = new StringBuilder(); sb.AppendLine("public static class PipelineProviderExtensions"); sb.AppendLine("{"); sb.AppendLine( " public static IServiceCollection AddPipelineProvider(this IServiceCollection services)"); sb.AppendLine(" where TInterface : class"); sb.AppendLine(" where TImplementation : class, TInterface"); sb.AppendLine(" {"); sb.AppendLine(" services.AddScoped();"); sb.AppendLine(" services.AddScoped(sp => sp.GetRequiredService());"); sb.AppendLine(" return services;"); sb.AppendLine(" }"); sb.AppendLine("}"); return sb.ToString(); } private static string BuildPipelineNodeExtensionsClass() { var sb = new StringBuilder(); sb.AppendLine("public static class PipelineNodeExtensions"); sb.AppendLine("{"); sb.AppendLine(" public static IServiceCollection AddPipelineNode(this IServiceCollection services)"); sb.AppendLine(" where TNode : class, INode"); sb.AppendLine(" {"); sb.AppendLine(" services.AddScoped();"); sb.AppendLine(" return services;"); sb.AppendLine(" }"); sb.AppendLine("}"); return sb.ToString(); } private static string BuildPipelineNodeValidatorExtensionsClass() { var sb = new StringBuilder(); sb.AppendLine("public static class PipelineNodeValidatorExtensions"); sb.AppendLine("{"); sb.AppendLine( " public static IServiceCollection AddPipelineNodeValidator(this IServiceCollection services)"); sb.AppendLine(" where TValidator : class, INodeValidator"); sb.AppendLine(" {"); sb.AppendLine(" services.AddTransient();"); sb.AppendLine(" return services;"); sb.AppendLine(" }"); sb.AppendLine("}"); return sb.ToString(); } private static string BuildPipelineFieldValidatorExtensionsClass() { var sb = new StringBuilder(); sb.AppendLine("public static class PipelineFieldValidatorExtensions"); sb.AppendLine("{"); sb.AppendLine( " public static IServiceCollection AddPipelineNodeFieldValidator(this IServiceCollection services)"); sb.AppendLine(" where TValidator : class, INodeFieldValidator"); sb.AppendLine(" {"); sb.AppendLine(" services.AddTransient();"); sb.AppendLine(" return services;"); sb.AppendLine(" }"); sb.AppendLine("}"); return sb.ToString(); } }