< Summary

Information
Class: NexusLabs.Needlr.Generators.OptionsAttribute
Assembly: NexusLabs.Needlr.Generators.Attributes
File(s): /home/runner/work/needlr/needlr/src/NexusLabs.Needlr.Generators.Attributes/OptionsAttribute.cs
Line coverage
90%
Covered lines: 9
Uncovered lines: 1
Coverable lines: 10
Total lines: 173
Line coverage: 90%
Branch coverage
N/A
Covered branches: 0
Total branches: 0
Branch coverage: N/A
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor()100%11100%
.ctor(...)100%11100%
get_SectionName()100%11100%
get_Name()100%11100%
get_ValidateOnStart()100%11100%
get_ValidateMethod()100%210%
get_Validator()100%11100%

File(s)

/home/runner/work/needlr/needlr/src/NexusLabs.Needlr.Generators.Attributes/OptionsAttribute.cs

#LineLine coverage
 1using System;
 2
 3namespace NexusLabs.Needlr.Generators;
 4
 5/// <summary>
 6/// Marks a class as an options/configuration type that should be bound to a configuration section.
 7/// The source generator will automatically generate the <c>services.Configure&lt;T&gt;()</c> call.
 8/// </summary>
 9/// <remarks>
 10/// <para>
 11/// When applied to a class, the generator will emit code to bind the class to a configuration section.
 12/// If no section name is specified, it is inferred from the class name by stripping common suffixes
 13/// (Options, Settings, Config).
 14/// </para>
 15/// <para>
 16/// All three options interfaces are registered automatically:
 17/// <list type="bullet">
 18/// <item><description><c>IOptions&lt;T&gt;</c> - Singleton, no reload</description></item>
 19/// <item><description><c>IOptionsSnapshot&lt;T&gt;</c> - Scoped, reloads per request</description></item>
 20/// <item><description><c>IOptionsMonitor&lt;T&gt;</c> - Singleton with change notifications</description></item>
 21/// </list>
 22/// </para>
 23/// </remarks>
 24/// <example>
 25/// <code>
 26/// // Section name inferred as "Database"
 27/// [Options]
 28/// public class DatabaseOptions
 29/// {
 30///     public string ConnectionString { get; set; } = "";
 31///     public int CommandTimeout { get; set; } = 30;
 32/// }
 33///
 34/// // Explicit section name
 35/// [Options("MyApp:Database")]
 36/// public class DbOptions
 37/// {
 38///     public string ConnectionString { get; set; } = "";
 39/// }
 40///
 41/// // With validation at startup
 42/// [Options(ValidateOnStart = true)]
 43/// public class StripeOptions
 44/// {
 45///     [Required]
 46///     public string ApiKey { get; set; } = "";
 47/// }
 48///
 49/// // Named options for multiple instances
 50/// [Options("Databases:Primary", Name = "Primary")]
 51/// [Options("Databases:Replica", Name = "Replica")]
 52/// public class ConnectionOptions
 53/// {
 54///     public string ConnectionString { get; set; } = "";
 55///     public bool ReadOnly { get; set; }
 56/// }
 57/// </code>
 58/// </example>
 59[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = true)]
 60public sealed class OptionsAttribute : Attribute
 61{
 62    /// <summary>
 63    /// Initializes a new instance of the <see cref="OptionsAttribute"/> class
 64    /// with the section name inferred from the class name.
 65    /// </summary>
 466    public OptionsAttribute()
 67    {
 468    }
 69
 70    /// <summary>
 71    /// Initializes a new instance of the <see cref="OptionsAttribute"/> class
 72    /// with an explicit section name.
 73    /// </summary>
 74    /// <param name="sectionName">
 75    /// The configuration section name to bind to (e.g., "Database" or "MyApp:Database").
 76    /// </param>
 738577    public OptionsAttribute(string sectionName)
 78    {
 738579        SectionName = sectionName;
 738580    }
 81
 82    /// <summary>
 83    /// Gets the configuration section name to bind to.
 84    /// If null, the section name is inferred from the class name.
 85    /// </summary>
 286    public string? SectionName { get; }
 87
 88    /// <summary>
 89    /// Gets or sets the name for named options.
 90    /// When set, registers as a named option that can be retrieved via
 91    /// <c>IOptionsSnapshot&lt;T&gt;.Get(name)</c> or <c>IOptionsMonitor&lt;T&gt;.Get(name)</c>.
 92    /// </summary>
 93    /// <remarks>
 94    /// Use this when you need multiple configurations of the same options type,
 95    /// such as primary and replica database connections.
 96    /// </remarks>
 123397    public string? Name { get; set; }
 98
 99    /// <summary>
 100    /// Gets or sets a value indicating whether to validate the options at application startup.
 101    /// When true, validation errors will prevent the application from starting.
 102    /// </summary>
 103    /// <remarks>
 104    /// <para>
 105    /// When enabled, the generator will emit:
 106    /// <list type="bullet">
 107    /// <item><description><c>.ValidateDataAnnotations()</c> - Validates [Required], [Range], etc.</description></item>
 108    /// <item><description><c>.ValidateOnStart()</c> - Runs validation during startup</description></item>
 109    /// </list>
 110    /// </para>
 111    /// <para>
 112    /// For custom validation, implement a <c>Validate()</c> method returning <c>IEnumerable&lt;ValidationError&gt;</c>,
 113    /// or specify an external validator using the <see cref="Validator"/> property.
 114    /// </para>
 115    /// </remarks>
 1236116    public bool ValidateOnStart { get; set; }
 117
 118    /// <summary>
 119    /// Gets or sets the name of the validation method to use.
 120    /// </summary>
 121    /// <remarks>
 122    /// <para>
 123    /// By default (when null), the generator looks for a method named <c>Validate</c>.
 124    /// Set this property to use a differently-named method.
 125    /// </para>
 126    /// <para>
 127    /// The method must return <c>IEnumerable&lt;ValidationError&gt;</c> (or <c>IEnumerable&lt;string&gt;</c>
 128    /// for backward compatibility) and take no parameters (for instance methods) or the options
 129    /// type as a parameter (for static methods).
 130    /// </para>
 131    /// </remarks>
 132    /// <example>
 133    /// <code>
 134    /// [Options(ValidateOnStart = true, ValidateMethod = nameof(CheckConfig))]
 135    /// public class MyOptions
 136    /// {
 137    ///     public IEnumerable&lt;ValidationError&gt; CheckConfig()
 138    ///     {
 139    ///         if (string.IsNullOrEmpty(Value))
 140    ///             yield return "Value is required";
 141    ///     }
 142    /// }
 143    /// </code>
 144    /// </example>
 0145    public string? ValidateMethod { get; set; }
 146
 147    /// <summary>
 148    /// Gets or sets the external validator type to use.
 149    /// </summary>
 150    /// <remarks>
 151    /// <para>
 152    /// When set, validation is delegated to the specified type instead of a method on the options class.
 153    /// The validator type must implement <c>IOptionsValidator&lt;T&gt;</c> or FluentValidation's
 154    /// <c>AbstractValidator&lt;T&gt;</c> (if FluentValidation is referenced).
 155    /// </para>
 156    /// <para>
 157    /// Can be combined with <see cref="ValidateMethod"/> to specify a custom method name on the
 158    /// validator type (default is <c>Validate</c>).
 159    /// </para>
 160    /// </remarks>
 161    /// <example>
 162    /// <code>
 163    /// [Options(ValidateOnStart = true, Validator = typeof(MyOptionsValidator))]
 164    /// public class MyOptions { ... }
 165    ///
 166    /// public class MyOptionsValidator : IOptionsValidator&lt;MyOptions&gt;
 167    /// {
 168    ///     public IEnumerable&lt;ValidationError&gt; Validate(MyOptions options) { ... }
 169    /// }
 170    /// </code>
 171    /// </example>
 617172    public Type? Validator { get; set; }
 173}