< Summary

Information
Class: NexusLabs.Needlr.Injection.Reflection.ReflectionFallbackHandlers
Assembly: NexusLabs.Needlr.Injection.Reflection
File(s): /home/runner/work/needlr/needlr/src/NexusLabs.Needlr.Injection.Reflection/ReflectionFallbackHandlers.cs
Line coverage
100%
Covered lines: 41
Uncovered lines: 0
Coverable lines: 41
Total lines: 105
Line coverage: 100%
Branch coverage
75%
Covered branches: 3
Total branches: 4
Branch coverage: 75%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
ThrowException(...)75%44100%
LogWarning(...)100%11100%
Silent(...)100%11100%
CreateTypeRegistrarContext()100%11100%
CreateTypeFiltererContext()100%11100%
CreatePluginFactoryContext()100%11100%
CreateAssemblyProviderContext()100%11100%

File(s)

/home/runner/work/needlr/needlr/src/NexusLabs.Needlr.Injection.Reflection/ReflectionFallbackHandlers.cs

#LineLine coverage
 1using NexusLabs.Needlr.Injection.Reflection.PluginFactories;
 2using NexusLabs.Needlr.Injection.Reflection.TypeFilterers;
 3using NexusLabs.Needlr.Injection.Reflection.TypeRegistrars;
 4
 5namespace NexusLabs.Needlr.Injection.Reflection;
 6
 7/// <summary>
 8/// Provides built-in handlers for reflection fallback scenarios.
 9/// Use these with <see cref="SyringeReflectionExtensions.WithReflectionFallbackHandler"/> to control
 10/// what happens when source-generated components are not available.
 11/// </summary>
 12public static class ReflectionFallbackHandlers
 13{
 14    /// <summary>
 15    /// A handler that throws an <see cref="InvalidOperationException"/> when reflection fallback occurs.
 16    /// Use this to enforce source-generation in AOT/trimmed applications.
 17    /// </summary>
 18    /// <example>
 19    /// <code>
 20    /// var syringe = new Syringe()
 21    ///     .WithReflectionFallbackHandler(ReflectionFallbackHandlers.ThrowException);
 22    /// </code>
 23    /// </example>
 24    public static void ThrowException(ReflectionFallbackContext context)
 25    {
 426        ArgumentNullException.ThrowIfNull(context);
 427        throw new InvalidOperationException(
 428            $"Reflection fallback detected for {context.ComponentName}. " +
 429            $"{context.Reason} " +
 430            $"Expected: {context.GeneratedComponentType?.Name ?? "source-generated component"}, " +
 431            $"Fallback: {context.ReflectionComponentType.Name}. " +
 432            "Add [assembly: GenerateTypeRegistry(...)] to enable source generation, " +
 433            "or call .UsingReflection() to explicitly opt into reflection-based discovery.");
 34    }
 35
 36    /// <summary>
 37    /// A handler that writes a warning to <see cref="Console.Error"/> when reflection fallback occurs.
 38    /// Useful for development/debugging to identify missing source generation.
 39    /// </summary>
 40    /// <example>
 41    /// <code>
 42    /// var syringe = new Syringe()
 43    ///     .WithReflectionFallbackHandler(ReflectionFallbackHandlers.LogWarning);
 44    /// </code>
 45    /// </example>
 46    public static void LogWarning(ReflectionFallbackContext context)
 47    {
 148        ArgumentNullException.ThrowIfNull(context);
 149        Console.Error.WriteLine(
 150            $"[Needlr Warning] Reflection fallback for {context.ComponentName}: {context.Reason}");
 151    }
 52
 53    /// <summary>
 54    /// A handler that does nothing when reflection fallback occurs.
 55    /// This is the default behavior - silent fallback to reflection.
 56    /// </summary>
 57    public static void Silent(ReflectionFallbackContext context)
 58    {
 59        // Intentionally empty - silent fallback
 160    }
 61
 62    /// <summary>
 63    /// Creates context for TypeRegistrar fallback.
 64    /// </summary>
 665    public static ReflectionFallbackContext CreateTypeRegistrarContext() => new()
 666    {
 667        ComponentName = "TypeRegistrar",
 668        Reason = "No source-generated TypeRegistry found via NeedlrSourceGenBootstrap.",
 669        ReflectionComponentType = typeof(ReflectionTypeRegistrar),
 670        GeneratedComponentType = null
 671    };
 72
 73    /// <summary>
 74    /// Creates context for TypeFilterer fallback.
 75    /// </summary>
 276    public static ReflectionFallbackContext CreateTypeFiltererContext() => new()
 277    {
 278        ComponentName = "TypeFilterer",
 279        Reason = "No source-generated TypeRegistry found via NeedlrSourceGenBootstrap.",
 280        ReflectionComponentType = typeof(ReflectionTypeFilterer),
 281        GeneratedComponentType = null
 282    };
 83
 84    /// <summary>
 85    /// Creates context for PluginFactory fallback.
 86    /// </summary>
 187    public static ReflectionFallbackContext CreatePluginFactoryContext() => new()
 188    {
 189        ComponentName = "PluginFactory",
 190        Reason = "No source-generated TypeRegistry found via NeedlrSourceGenBootstrap.",
 191        ReflectionComponentType = typeof(ReflectionPluginFactory),
 192        GeneratedComponentType = null
 193    };
 94
 95    /// <summary>
 96    /// Creates context for AssemblyProvider fallback.
 97    /// </summary>
 198    public static ReflectionFallbackContext CreateAssemblyProviderContext() => new()
 199    {
 1100        ComponentName = "AssemblyProvider",
 1101        Reason = "No source-generated TypeRegistry found via NeedlrSourceGenBootstrap.",
 1102        ReflectionComponentType = typeof(AssemblyProviderBuilder),
 1103        GeneratedComponentType = null
 1104    };
 105}