< Summary

Information
Class: MyNet.Humanizer.Display.DisplayTextStrategyResolver
Assembly: MyNet.Humanizer
File(s): https://raw.githubusercontent.com/sandre58/MyNet/85372080fe102cd9ee155ceab49ae000e7f66103/src/MyNet.Humanizer/Display/DisplayTextStrategyResolver.cs
Tag: 323_28699572109
Line coverage
77%
Covered lines: 17
Uncovered lines: 5
Coverable lines: 22
Total lines: 86
Line coverage: 77.2%
Branch coverage
37%
Covered branches: 6
Total branches: 16
Branch coverage: 37.5%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
TryGet(...)50%2260%
GetRequired()50%22100%
GetRequiredForType(...)50%22100%
Resolve(...)30%131070%

File(s)

https://raw.githubusercontent.com/sandre58/MyNet/85372080fe102cd9ee155ceab49ae000e7f66103/src/MyNet.Humanizer/Display/DisplayTextStrategyResolver.cs

#LineLine coverage
 1// -----------------------------------------------------------------------
 2// <copyright file="DisplayTextStrategyResolver.cs" company="Stéphane ANDRE">
 3// Copyright (c) Stéphane ANDRE. All rights reserved.
 4// </copyright>
 5// -----------------------------------------------------------------------
 6
 7using System;
 8using System.Collections.Concurrent;
 9using System.Diagnostics.CodeAnalysis;
 10using System.Linq;
 11using MyNet.Humanizer.Display.Registration;
 12
 13namespace MyNet.Humanizer.Display;
 14
 15/// <summary>
 16/// Resolves display name providers using deterministic hierarchical fallback.
 17/// Resolution order is: exact type, interfaces, base types, then object.
 18/// </summary>
 19public sealed class DisplayTextStrategyResolver(IDisplayTextStrategyRegistry registry) : IDisplayTextStrategyResolver
 20{
 3121    private readonly ConcurrentDictionary<Type, IDisplayTextStrategy?> _cache = new();
 22
 23    /// <inheritdoc/>
 24    public bool TryGet<T>([NotNullWhen(true)] out IDisplayTextStrategy<T>? strategy)
 25        where T : notnull
 26    {
 1527        if (_cache.GetOrAdd(typeof(T), Resolve) is { } result)
 28        {
 1529            strategy = new TypedDisplayTextStrategyAdapter<T>(result);
 1530            return true;
 31        }
 32
 033        strategy = null;
 034        return false;
 35    }
 36
 37    /// <inheritdoc/>
 38    public IDisplayTextStrategy<T> GetRequired<T>()
 39        where T : notnull
 1540        => TryGet<T>(out var s)
 1541            ? s
 1542            : throw new InvalidOperationException($"No display text strategy registered for '{typeof(T).FullName}'.");
 43
 44    /// <inheritdoc/>
 45    public IDisplayTextStrategy GetRequiredForType(Type type)
 46    {
 10447        ArgumentNullException.ThrowIfNull(type);
 48
 10449        return _cache.GetOrAdd(type, Resolve)
 10450            ?? throw new InvalidOperationException($"No display text strategy registered for '{type.FullName}'.");
 51    }
 52
 53    /// <summary>
 54    /// Resolves a display name provider for the requested type using hierarchical fallback:
 55    /// 1. Exact match: provider registered for the requested type.
 56    /// 2. Assignable fallback: provider registered for an interface or base type assignable from the requested type.
 57    /// 3. Enum fallback: provider registered for Enum if the requested type is an enum (important case).
 58    /// 4. Object fallback: provider registered for object.
 59    /// </summary>
 60    /// <param name="requestedType">The type for which to resolve a display name provider.</param>
 61    /// <returns>The resolved display name provider, or null if none is found.</returns>
 62    private IDisplayTextStrategy? Resolve(Type requestedType)
 63    {
 64        // 1. exact match
 3565        if (registry.TryGetStrategy(requestedType, out var exact))
 566            return exact;
 67
 68        // 2. assignable fallback (interfaces / base types)
 3069        var fallback = registry
 3070            .Strategies
 3071            .FirstOrDefault(x => x.Key.IsAssignableFrom(requestedType));
 72
 3073        if (fallback.Value is not null)
 3074            return fallback.Value;
 75
 76        // 3. Enum fallback (important case)
 077        if (requestedType.IsEnum && registry.TryGetStrategy(typeof(Enum), out var enumStrategy))
 78        {
 079            return enumStrategy;
 80        }
 81
 82        // 4. object fallback (optional global default)
 083        return registry.TryGetStrategy(typeof(object), out var objectStrategy) ? objectStrategy : null;
 84    }
 85}
 86