< Summary

Information
Class: NexusLabs.Needlr.ServiceRegistrationInfo
Assembly: NexusLabs.Needlr
File(s): /home/runner/work/needlr/needlr/src/NexusLabs.Needlr/ServiceRegistrationInfo.cs
Line coverage
96%
Covered lines: 28
Uncovered lines: 1
Coverable lines: 29
Total lines: 105
Line coverage: 96.5%
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
get_ServiceDescriptor()100%11100%
get_ServiceType()100%11100%
get_ImplementationType()100%11100%
get_Lifetime()100%11100%
get_HasFactory()100%11100%
get_HasInstance()100%11100%
ToDetailedString()87.5%88100%
FormatTypeName(...)83.33%6690%

File(s)

/home/runner/work/needlr/needlr/src/NexusLabs.Needlr/ServiceRegistrationInfo.cs

#LineLine coverage
 1using Microsoft.Extensions.DependencyInjection;
 2
 3using System.Text;
 4
 5namespace NexusLabs.Needlr;
 6
 7public readonly record struct ServiceRegistrationInfo(
 59398    ServiceDescriptor ServiceDescriptor)
 9{
 10    /// <summary>
 11    /// Gets the service (abstraction/contract) <see cref="Type"/> that was registered.
 12    /// This is the key used by the DI container for resolution requests.
 13    /// </summary>
 355414    public Type ServiceType => ServiceDescriptor.ServiceType;
 15
 16    /// <summary>
 17    /// Gets the concrete implementation <see cref="Type"/>, if the registration
 18    /// was made with an implementation type. Returns <see langword="null"/> when:
 19    /// <list type="bullet">
 20    ///   <item>The registration uses an <see cref="ServiceDescriptor.ImplementationFactory"/>.</item>
 21    ///   <item>The registration supplies a pre-built <see cref="ServiceDescriptor.ImplementationInstance"/>.</item>
 22    ///   <item>The registration represents an open generic without a concrete close (rare in reflection scenarios).</it
 23    /// </list>
 24    /// </summary>
 3825    public Type? ImplementationType => ServiceDescriptor.ImplementationType;
 26
 27    /// <summary>
 28    /// Gets the lifetime (<see cref="ServiceLifetime.Singleton"/>,
 29    /// <see cref="ServiceLifetime.Scoped"/>, or <see cref="ServiceLifetime.Transient"/>)
 30    /// associated with the registration.
 31    /// </summary>
 106632    public ServiceLifetime Lifetime => ServiceDescriptor.Lifetime;
 33
 34    /// <summary>
 35    /// Indicates whether the registration was configured with a factory delegate
 36    /// (<see cref="ServiceDescriptor.ImplementationFactory"/>). When <see langword="true"/>,
 37    /// <see cref="ImplementationType"/> will be <see langword="null"/>.
 38    /// </summary>
 2139    public bool HasFactory => ServiceDescriptor.ImplementationFactory is not null;
 40
 41    /// <summary>
 42    /// Indicates whether the registration was configured with a pre-constructed
 43    /// instance (<see cref="ServiceDescriptor.ImplementationInstance"/>). When
 44    /// <see langword="true"/>, <see cref="ImplementationType"/> will typically be
 45    /// <see langword="null"/> (unless metadata reflects the instance's type indirectly).
 46    /// </summary>
 2047    public bool HasInstance => ServiceDescriptor.ImplementationInstance is not null;
 48
 49    /// <summary>
 50    /// Returns a detailed, formatted string representation of this registration
 51    /// suitable for debugging and diagnostics.
 52    /// </summary>
 53    /// <returns>A multi-line formatted string with registration details.</returns>
 54    public string ToDetailedString()
 55    {
 1956        var sb = new StringBuilder();
 1957        var serviceTypeName = FormatTypeName(ServiceType);
 58
 1959        sb.AppendLine($"┌─ {serviceTypeName}");
 1960        sb.AppendLine($"│  Lifetime: {Lifetime}");
 61
 1962        if (HasInstance)
 63        {
 264            var instanceType = ServiceDescriptor.ImplementationInstance?.GetType();
 265            sb.AppendLine($"│  Implementation: Instance ({FormatTypeName(instanceType)})");
 66        }
 1767        else if (HasFactory)
 68        {
 169            sb.AppendLine($"│  Implementation: Factory");
 70        }
 1671        else if (ImplementationType is not null)
 72        {
 1673            sb.AppendLine($"│  Implementation: {FormatTypeName(ImplementationType)}");
 74        }
 75
 1976        sb.Append($"└─");
 77
 1978        return sb.ToString();
 79    }
 80
 81    private static string FormatTypeName(Type? type)
 82    {
 3983        if (type is null)
 84        {
 085            return "<unknown>";
 86        }
 87
 3988        if (!type.IsGenericType)
 89        {
 3590            return type.Name;
 91        }
 92
 493        if (type.IsGenericTypeDefinition)
 94        {
 95            // Open generic: IGenericService<>
 296            var baseName = type.Name.Split('`')[0];
 297            return $"{baseName}<>";
 98        }
 99
 100        // Closed generic: IGenericService<String>
 2101        var genericBaseName = type.Name.Split('`')[0];
 2102        var genericArgs = string.Join(", ", type.GetGenericArguments().Select(FormatTypeName));
 2103        return $"{genericBaseName}<{genericArgs}>";
 104    }
 105}