AMillo.OptionSettings 1.0.0

dotnet add package AMillo.OptionSettings --version 1.0.0
NuGet\Install-Package AMillo.OptionSettings -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="AMillo.OptionSettings" Version="1.0.0" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add AMillo.OptionSettings --version 1.0.0
#r "nuget: AMillo.OptionSettings, 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.
// Install AMillo.OptionSettings as a Cake Addin
#addin nuget:?package=AMillo.OptionSettings&version=1.0.0

// Install AMillo.OptionSettings as a Cake Tool
#tool nuget:?package=AMillo.OptionSettings&version=1.0.0

About The Project

OptionSettings is a simple feature that allows you to register your configuration/setting classes without having to add them to the Program / Startup file, keeping them clean and smooth.

  • Follow best practices using Options Pattern
  • Cleaner and readable Program / Startup files, keep them small.
  • Make your configuration/setting classes ready-to-use just as you finish creating them, you don't even need to go into the Program / Startup file.

Getting Started

Installation

  • .NET CLI
    dotnet add package AMillo.OptionSettings --version 1.0.0
    
  • Package Manager
    Install-Package AMillo.OptionSettings -Version 1.0.0
    

Usage

  1. Add the following using directive on your Program.cs / Startup.cs file

     using AMillo.OptionSettings.Extensions.DependencyInjection;
    
  2. Call the AddOptionSettings extension method using one of the following overloads

    • builder.AddOptionSettings()
      //Add all configuration classes marked with [OptionSettings] attribute from all assemblies in the current AppDomain
      //Uses builder.Configuration by default to bind the settings
      builder.AddOptionSettings();
      
    • builder.AddOptionSettingsFromAssemblies(IEnumerable<Assembly> assemblies)
      //Add all configuration classes marked with [OptionSettings] attribute from specified assemblies
      //Uses builder.Configuration by default to bind the settings
      builder.AddOptionSettingsFromAssemblies(AppDomain.CurrentDomain.GetAssemblies()); 
      
    • builder.AddOptionSettingsFromAssembly(Assembly assembly)
      //Add all configuration classes marked with [OptionSettings] attribute from specified assembly
      //Uses builder.Configuration by default to bind the settings
      builder.AddOptionSettingsFromAssembly(typeof(Program).Assembly);
      
    • builder.Services.AddOptionSettings(IConfiguration configuration)
      //Add all configuration classes marked with [OptionSettings] attribute from all assemblies in the current AppDomain
      //Also uses the specified configuration to bind the settings
      builder.Services.AddOptionSettings(builder.Configuration);
      
    • builder.Services.AddOptionSettingsFromAssembly(Assembly assembly, IConfiguration configuration)
      //Add all configuration classes marked with [OptionSettings] attribute from specified assembly
      //Also uses the specified configuration to bind the settings
      builder.Services.AddOptionSettingsFromAssembly(typeof(Program).Assembly, builder.Configuration);
      
    • builder.Services.AddOptionSettingsFromAssemblies(IEnumerable<Assembly> assemblies, IConfiguration configuration)
      //Add all configuration classes marked with [OptionSettings] attribute from specified assemblies
      //Also uses the specified configuration to bind the settings
      builder.Services.AddOptionSettingsFromAssemblies(AppDomain.CurrentDomain.GetAssemblies(), builder.Configuration);
      
  3. Mark your configuration class with the [OptionSettings] attribute.

       using AMillo.OptionSettings.Attributes;
    
       [OptionSettings(sectionName: Constants.AppSettings.Sample)]
       internal sealed class SampleConfiguration
       {
           public string SampleKey { get; set; } = string.Empty;
           public int SampleNumber { get; set; } = 0;
       }
    
  4. That's it! Now you can start using you configuration class following the Options pattern with IOptions, IOptionsMonitor or IOptionsSnapshot.

Important

You need to specify the "sectionName" to the attribute's constructor, this value needs to match the section in your AppSettings file from where you want your configuration/setting class get configured. This is how the AppSettings.json file looks like for the previous example:

  "SampleConfiguration": {
    "SampleKey": "SomeKey",
    "SampleNumber": 1234567890
  }

Validations

OptionSettings has full support for you to validate your configuration classes as much as you like.

1. Set the ValidationMode in the [OptionSettings] attribute:
  • ValidationMode.None: This is the default, with this option your configuration class will not be validated at all.
  using AMillo.OptionSettings.Attributes;
  using AMIllo.OptionSettings.Enums;
  
  [OptionSettings(
      sectionName: Constants.AppSettings.Sample, 
      ValidationMode = ValidationMode.None)]
  internal sealed class SampleConfiguration { }
  • ValidationMode.Startup: The values will be validated when the application starts.
  using AMillo.OptionSettings.Attributes;
  using AMIllo.OptionSettings.Enums;

  [OptionSettings(
      sectionName: Constants.AppSettings.Sample, 
      ValidationMode = ValidationMode.Startup)]
  internal sealed class SampleConfiguration { }
  • ValidationMode.Runtime: The values will be validated on runtime when trying to access the configuration class.
  using AMillo.OptionSettings.Attributes;
  using AMIllo.OptionSettings.Enums;

  [OptionSettings(
      sectionName: Constants.AppSettings.Sample, 
      ValidationMode = ValidationMode.Runtime)]
  internal sealed class SampleConfiguration { }

NOTE: Personally. I recommend using <strong>ValidationMode.Startup</strong> so the application can not run with invalid configuration values and fails as soon as possible, at startup time.

2. Add DataAnnotations to validate your configuration class properties:
  using AMillo.OptionSettings.Attributes;
  using AMIllo.OptionSettings.Enums;
  using System.ComponentModel.DataAnnotations;
  
  [OptionSettings(
      sectionName: Constants.AppSettings.Sample, 
      ValidationMode = ValidationMode.Startup)]
  internal sealed class SampleConfiguration
  {
      [Required]
      [MaxLength(20)]
      public string SampleKey { get; set; } = string.Empty;
  
      [Required]
      [Range(0, 10)]
      public int SampleNumber { get; set; } = 0;
  }
3. You can also add multiple validation methods and mark them with the [OptionSettingsValidation] attribute. This allows you validate your configuration class values in more complex ways.
  • The methods must have the following signature:
      bool AnyMethodName(TOptions options)
    
    Where TOptions is your configuration class.
  • You can pass a FailureMessage to the [OptionSettingsValidation] attribute if you want to show a custom message if the validation fails.
      [OptionSettingsValidation(FailureMessage = "Custom failure messsage")]
    
  • The methods only returns true indicating the validation succeeded or false indicating the validation has failed.
  • These validations methods will run depending on the value you have configured into the ValidationMode option.
  using AMillo.OptionSettings.Attributes;
  using AMIllo.OptionSettings.Enums;
  using System.ComponentModel.DataAnnotations;
  
  [OptionSettings(
    sectionName: Constants.AppSettings.Sample, 
    ValidationMode = ValidationMode.Runtime)]
  internal sealed class SampleConfiguration
  {
    [Required]
    [MaxLength(20)]
    public string SampleKey { get; set; } = string.Empty;
  
    [Required]
    [Range(0, 10)]
    public int SampleNumber { get; set; } = 0;
  
    public string SampleString { get; set; } = string.Empty;
  
    [OptionSettingsValidation(FailureMessage = "SampleString can't contain vowels.")]
    public static bool ValidateSampleString(SampleConfiguration options)
    {
        HashSet<char> vowels = ['a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U'];
  
        foreach (char @char in options.SampleString)
        {
            if (vowels.Contains(@char))
            {
                return false;
            }
        }
  
        return true;
    }
  
    [OptionSettingsValidation(FailureMessage = "SampleNumber must be 1 when SampleKey is 'one'")]
    public static bool ValidateSampleNumber(SampleConfiguration options)
    {
        if(options.SampleKey == "one" && options.SampleNumber != 1)
        {
            return false;
        }
  
        return true;
    }
  }

Contributing

Visit the source repository for full documentation and contributing instructions:

Contact

Alejo Millo - alejo.millo@outlook.com

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.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 68 5/12/2024