< Summary

Information
Class: NexusLabs.Needlr.Generators.CodeGen.ComposedRegistrationsCodeGenerator
Assembly: NexusLabs.Needlr.Generators
File(s): /home/runner/work/needlr/needlr/src/NexusLabs.Needlr.Generators/CodeGen/ComposedRegistrationsCodeGenerator.cs
Line coverage
93%
Covered lines: 28
Uncovered lines: 2
Coverable lines: 30
Total lines: 71
Line coverage: 93.3%
Branch coverage
85%
Covered branches: 12
Total branches: 14
Branch coverage: 85.7%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
GenerateRegisterComposedTypesMethod(...)80%101091.66%
GetAddMethod(...)100%44100%

File(s)

/home/runner/work/needlr/needlr/src/NexusLabs.Needlr.Generators/CodeGen/ComposedRegistrationsCodeGenerator.cs

#LineLine coverage
 1// Copyright (c) NexusLabs. All rights reserved.
 2// Licensed under the MIT License.
 3
 4using System.Collections.Generic;
 5using System.Linq;
 6using System.Text;
 7
 8using NexusLabs.Needlr.Generators.Models;
 9
 10namespace NexusLabs.Needlr.Generators.CodeGen;
 11
 12/// <summary>
 13/// Generates the <c>RegisterComposedTypes(IServiceCollection)</c> method that registers each open generic
 14/// composition type closed over the type argument(s) of every discovered implementation of its designated
 15/// open generic interface, exposed as the designated facade service type.
 16/// </summary>
 17internal static class ComposedRegistrationsCodeGenerator
 18{
 19    /// <summary>
 20    /// Emits the <c>RegisterComposedTypes(IServiceCollection)</c> method body into the TypeRegistry class.
 21    /// </summary>
 22    internal static void GenerateRegisterComposedTypesMethod(
 23        StringBuilder builder,
 24        IReadOnlyList<DiscoveredComposedRegistration> registrations,
 25        BreadcrumbWriter breadcrumbs,
 26        string? projectDirectory)
 27    {
 4228        builder.AppendLine("    /// <summary>");
 4229        builder.AppendLine("    /// Registers each composition type closed over the type argument(s) of every discovered
 4230        builder.AppendLine("    /// implementation of its designated open generic interface, exposed as the designated f
 4231        builder.AppendLine("    /// </summary>");
 4232        builder.AppendLine("    /// <param name=\"services\">The service collection to register to.</param>");
 4233        builder.AppendLine("    private static void RegisterComposedTypes(IServiceCollection services)");
 4234        builder.AppendLine("    {");
 35
 19236        foreach (var registration in registrations)
 37        {
 5438            var addMethod = GetAddMethod(registration.Lifetime);
 5439            var closedShortName = registration.ClosedCompositionTypeName.Split('.').Last();
 5440            var facadeShortName = registration.FacadeTypeName.Split('.').Last();
 5441            var sourcePath = registration.SourceFilePath != null
 5442                ? BreadcrumbWriter.GetRelativeSourcePath(registration.SourceFilePath, projectDirectory)
 5443                : $"[{registration.AssemblyName}]";
 44
 5445            breadcrumbs.WriteInlineComment(builder, "        ", $"Composed: {closedShortName} as {facadeShortName} ← {so
 46
 5447            if (registration.ConstructorArguments.Count == 0)
 48            {
 049                builder.AppendLine($"        services.{addMethod}<{registration.FacadeTypeName}>(sp => new {registration
 050                continue;
 51            }
 52
 5453            builder.AppendLine($"        services.{addMethod}<{registration.FacadeTypeName}>(sp => new {registration.Clo
 54
 23055            for (var i = 0; i < registration.ConstructorArguments.Count; i++)
 56            {
 6157                var isLast = i == registration.ConstructorArguments.Count - 1;
 6158                builder.AppendLine($"            {registration.ConstructorArguments[i]}{(isLast ? "));" : ",")}");
 59            }
 60        }
 61
 4262        builder.AppendLine("    }");
 4263    }
 64
 5465    private static string GetAddMethod(GeneratorLifetime lifetime) => lifetime switch
 5466    {
 267        GeneratorLifetime.Scoped => "AddScoped",
 268        GeneratorLifetime.Transient => "AddTransient",
 5069        _ => "AddSingleton",
 5470    };
 71}