RepletoryLib.Configuration 1.0.0

dotnet add package RepletoryLib.Configuration --version 1.0.0
                    
NuGet\Install-Package RepletoryLib.Configuration -Version 1.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="RepletoryLib.Configuration" Version="1.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="RepletoryLib.Configuration" Version="1.0.0" />
                    
Directory.Packages.props
<PackageReference Include="RepletoryLib.Configuration" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add RepletoryLib.Configuration --version 1.0.0
                    
#r "nuget: RepletoryLib.Configuration, 1.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package RepletoryLib.Configuration@1.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=RepletoryLib.Configuration&version=1.0.0
                    
Install as a Cake Addin
#tool nuget:?package=RepletoryLib.Configuration&version=1.0.0
                    
Install as a Cake Tool

RepletoryLib.Configuration

Configuration validation and extension helpers for RepletoryLib.

Part of the RepletoryLib ecosystem -- standalone, reusable .NET 10 libraries with zero business logic.

NuGet .NET 10 License: MIT


Overview

RepletoryLib.Configuration provides a streamlined approach to strongly-typed configuration with DataAnnotation-based validation and fail-fast startup behavior. Instead of discovering misconfigured settings at runtime, this package validates your configuration sections immediately when the application starts.

It also provides extension methods for reading required configuration values and a ReloadableOptions<T> wrapper that simplifies working with options that change at runtime when configuration sources are updated.

Key Features

  • DataAnnotation validation -- Validate options classes using [Required], [Range], [Url], and any other DataAnnotation attributes
  • Fail-fast startup -- Detect configuration errors before the first request is served
  • Reloadable options -- ReloadableOptions<T> wrapper with OnChange event for runtime configuration updates
  • Required values -- GetRequired<T>() extension ensures keys exist and are non-empty
  • Section binding -- GetSection<T>() extension for quick binding of configuration sections

Installation

dotnet add package RepletoryLib.Configuration

Or add to your .csproj:

<PackageReference Include="RepletoryLib.Configuration" Version="1.0.0" />

Note: RepletoryLib packages are published to a local BaGet feed. See the main repository README for feed configuration.

Dependencies

Package Type
RepletoryLib.Common RepletoryLib
Microsoft.Extensions.Configuration NuGet (10.0.0)
Microsoft.Extensions.Options NuGet (10.0.0)
Microsoft.Extensions.Options.DataAnnotations NuGet (10.0.0)

Quick Start

1. Define your options class with DataAnnotation attributes

using System.ComponentModel.DataAnnotations;

public class SmtpOptions
{
    public const string SectionName = "Smtp";

    [Required(ErrorMessage = "SMTP host is required")]
    public string Host { get; set; } = string.Empty;

    [Range(1, 65535, ErrorMessage = "Port must be between 1 and 65535")]
    public int Port { get; set; } = 587;

    [Required]
    [EmailAddress(ErrorMessage = "From address must be a valid email")]
    public string FromAddress { get; set; } = string.Empty;

    public string? Username { get; set; }
    public string? Password { get; set; }
    public bool UseSsl { get; set; } = true;
}

2. Register and validate in Program.cs

using RepletoryLib.Configuration;

var builder = WebApplication.CreateBuilder(args);

builder.Services
    .AddRepletoryConfiguration<SmtpOptions>(builder.Configuration, SmtpOptions.SectionName)
    .ValidateRepletoryConfigurationOnStartup<SmtpOptions>();

3. Add the configuration section to appsettings.json

{
  "Smtp": {
    "Host": "smtp.example.com",
    "Port": 587,
    "FromAddress": "noreply@example.com",
    "Username": "apikey",
    "Password": "SG.xxxxx",
    "UseSsl": true
  }
}

If Host or FromAddress is missing, the application will fail immediately at startup with a clear validation error.


Configuration

AddRepletoryConfiguration<TOptions> registers the following services:

  1. Binds TOptions to the specified configuration section via IOptions<TOptions>
  2. Registers ConfigurationValidator<TOptions> for DataAnnotation validation
  3. Registers ReloadableOptions<TOptions> as a singleton

ValidateRepletoryConfigurationOnStartup<TOptions> eagerly resolves IOptions<TOptions> during startup to trigger validation immediately.


Usage Examples

Fail-Fast Validation on Startup

Catch misconfiguration before the application accepts requests:

builder.Services
    .AddRepletoryConfiguration<DatabaseOptions>(builder.Configuration, "Database")
    .AddRepletoryConfiguration<RedisOptions>(builder.Configuration, "Redis")
    .AddRepletoryConfiguration<JwtOptions>(builder.Configuration, "Jwt")
    .ValidateRepletoryConfigurationOnStartup<DatabaseOptions>()
    .ValidateRepletoryConfigurationOnStartup<RedisOptions>()
    .ValidateRepletoryConfigurationOnStartup<JwtOptions>();

If any section fails validation, the application throws OptionsValidationException with details like:

DataAnnotation validation failed for 'DatabaseOptions' members: 'ConnectionString' with the error: 'ConnectionString is required'.

Reading Required Configuration Values

Use GetRequired<T>() to ensure a configuration key exists and is non-empty:

using RepletoryLib.Configuration.Extensions;

var connectionString = builder.Configuration.GetRequired<string>("ConnectionStrings:DefaultConnection");
var maxRetries = builder.Configuration.GetRequired<int>("Resilience:MaxRetries");

Throws InvalidOperationException if the key is missing, null, or cannot be converted.

Binding Configuration Sections

Use GetSection<T>() for quick binding without DI registration:

using RepletoryLib.Configuration.Extensions;

var smtpSettings = builder.Configuration.GetSection<SmtpOptions>("Smtp");
// smtpSettings is a new SmtpOptions instance with properties bound from config

Reloadable Options with Change Notifications

ReloadableOptions<T> wraps IOptionsMonitor<T> and fires an event when configuration changes at runtime:

public class EmailService
{
    private readonly ReloadableOptions<SmtpOptions> _options;

    public EmailService(ReloadableOptions<SmtpOptions> options)
    {
        _options = options;
        _options.OnChange += newOptions =>
        {
            Console.WriteLine($"SMTP config changed: now using {newOptions.Host}:{newOptions.Port}");
        };
    }

    public async Task SendAsync(string to, string subject, string body)
    {
        var smtp = _options.CurrentValue; // Always gets the latest value
        // ... send email using smtp.Host, smtp.Port, etc.
    }
}

Custom Validation Logic

Combine DataAnnotations with IValidateOptions<T> for complex rules:

using System.ComponentModel.DataAnnotations;

public class ApiOptions
{
    public const string SectionName = "Api";

    [Required]
    [Url(ErrorMessage = "BaseUrl must be a valid URL")]
    public string BaseUrl { get; set; } = string.Empty;

    [Range(1, 60, ErrorMessage = "Timeout must be between 1 and 60 seconds")]
    public int TimeoutSeconds { get; set; } = 30;

    [Range(0, 10)]
    public int MaxRetries { get; set; } = 3;

    [RegularExpression(@"^[a-zA-Z0-9-]+$", ErrorMessage = "ApiKey must be alphanumeric")]
    public string ApiKey { get; set; } = string.Empty;
}

API Reference

ConfigurationValidator<TOptions>

Implements IValidateOptions<TOptions>. Uses System.ComponentModel.DataAnnotations.Validator to validate options instances. Registered automatically by AddRepletoryConfiguration<TOptions>.

ReloadableOptions<TOptions>

Member Type Description
CurrentValue TOptions Gets the latest options value
OnChange event Action<TOptions> Fires when the underlying configuration changes
Dispose() void Unsubscribes from change notifications

Extension Methods

Method Description
IConfiguration.GetRequired<T>(key) Returns typed value or throws InvalidOperationException
IConfiguration.GetSection<T>(key) Binds section to a new T instance
IServiceCollection.AddRepletoryConfiguration<T>(config, sectionName) Registers options with binding, validation, and reloadable support
IServiceCollection.ValidateRepletoryConfigurationOnStartup<T>() Eagerly validates options on startup (fail-fast)

Integration with Other RepletoryLib Packages

Package Relationship
RepletoryLib.Common Direct dependency -- provides base types
RepletoryLib.Caching.Redis Use to validate RedisOptions on startup
RepletoryLib.Messaging.RabbitMQ Use to validate RabbitMqOptions on startup
RepletoryLib.Auth.Jwt Use to validate JwtOptions on startup
RepletoryLib.Logging Use to validate LoggingOptions on startup

Most RepletoryLib packages use the AddRepletoryConfiguration<T> pattern internally. You can also use it for your own application-specific options classes.


Testing

Configuration validation can be tested by creating invalid options and asserting that validation fails:

using Microsoft.Extensions.Options;

[Fact]
public void SmtpOptions_requires_host()
{
    var validator = new ConfigurationValidator<SmtpOptions>();
    var options = new SmtpOptions { Host = "" };

    var result = validator.Validate(null, options);

    result.Failed.Should().BeTrue();
    result.FailureMessage.Should().Contain("Host");
}

[Fact]
public void SmtpOptions_validates_port_range()
{
    var validator = new ConfigurationValidator<SmtpOptions>();
    var options = new SmtpOptions
    {
        Host = "smtp.example.com",
        FromAddress = "test@example.com",
        Port = 99999
    };

    var result = validator.Validate(null, options);

    result.Failed.Should().BeTrue();
    result.FailureMessage.Should().Contain("Port");
}

Troubleshooting

Issue Solution
OptionsValidationException on startup Check your appsettings.json section matches the SectionName and all [Required] properties are present
InvalidOperationException from GetRequired<T> The configuration key is missing or null -- add it to your configuration source
ReloadableOptions.OnChange not firing Ensure your configuration source supports reloading (e.g., appsettings.json with reloadOnChange: true)
Validation passes but values are wrong Verify the section name matches exactly (case-sensitive)

License

This project is licensed under the MIT License.

Copyright (c) 2024-2026 Repletory.


For complete documentation, infrastructure setup, and configuration reference, see the RepletoryLib main repository.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.0 138 3/2/2026