EnvoyConfig 1.0.0

dotnet add package EnvoyConfig --version 1.0.0
                    
NuGet\Install-Package EnvoyConfig -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="EnvoyConfig" Version="1.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="EnvoyConfig" Version="1.0.0" />
                    
Directory.Packages.props
<PackageReference Include="EnvoyConfig" />
                    
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 EnvoyConfig --version 1.0.0
                    
#r "nuget: EnvoyConfig, 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 EnvoyConfig@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=EnvoyConfig&version=1.0.0
                    
Install as a Cake Addin
#tool nuget:?package=EnvoyConfig&version=1.0.0
                    
Install as a Cake Tool

EnvoyConfig Logo

๐Ÿš€ EnvoyConfig

Build Status .NET NuGet License: LGPL-3.0-or-later GitHub Copilot Built with Claude Status: Pre-Release

EnvoyConfig is a modern C# library for .NET 8+ that loads strongly-typed configuration objects from environment variables at runtime using reflection. It supports advanced attribute-based mapping, type safety, nested objects, lists, dictionaries, and flexible prefixingโ€”all with minimal boilerplate.

โœจ Features

  • Attribute-based configuration: [Env] attribute for mapping properties to env vars
  • Supports primitives, enums, nullable types, lists, arrays, dictionaries, and nested objects
  • Multiple initialization modes: direct key, comma-separated/numbered lists, dictionary/map, nested prefix
  • Global/static prefix support
  • Logging integration with adapters (Microsoft, Serilog, NLog)
  • Thread-safe, high performance (caching)
  • Zero external dependencies in core

๐Ÿ“š Documentation

See here for Documentation.

๐Ÿ“ฆ Installation

dotnet add package EnvoyConfig

Optional:

dotnet add package EnvoyConfig.Adapters.Microsoft  # For Microsoft.Extensions.Logging

๐Ÿš€ Quick Start

public class ApiKeyConfig
{
    [Env(Key = "PRIMARY")]         // Maps to: MYAPP_API_PRIMARY
    public string Primary { get; set; } = "";

    [Env(Key = "SECONDARY")]       // Maps to: MYAPP_API_SECONDARY
    public string Secondary { get; set; } = "";

    [Env(Key = "ENABLED", Default = true)]  // Maps to: MYAPP_API_ENABLED
    public bool Enabled { get; set; }
}

public class MyConfig
{
    [Env(Key = "PORT", Default = 8080)]    // Maps to: MYAPP_PORT
    public int Port { get; set; }

    [Env(Key = "FEATURES", IsList = true)] // Maps to: MYAPP_FEATURES (comma-separated)
    public List<string> Features { get; set; } = new();

    [Env(NestedPrefix = "API_")]           // Maps to: MYAPP_API_* (nested object)
    public ApiKeyConfig ApiKeys { get; set; } = new();

    [Env(ListPrefix = "SERVER_")]          // Maps to: MYAPP_SERVER_1, MYAPP_SERVER_2, etc.
    public List<string> Servers { get; set; } = new();
}

// Set global prefix for all environment variables
EnvConfig.GlobalPrefix = "MYAPP_";

// Load configuration from environment variables
var config = EnvConfig.Load<MyConfig>();

// Save current configuration to .env file
EnvConfig.Save(config, "current-config.env");

// Save defaults template to .env file
EnvConfig.SaveDefaults<MyConfig>("template.env");

Example Environment Variables:

MYAPP_PORT=3000
MYAPP_FEATURES=auth,logging,metrics
MYAPP_API_PRIMARY=key123abc
MYAPP_API_SECONDARY=key456def
MYAPP_API_ENABLED=true
MYAPP_SERVER_1=api.example.com
MYAPP_SERVER_2=backup.example.com

๐Ÿ”ง Advanced Usage & Features

  • Prefix Handling: Set EnvConfig.GlobalPrefix to prepend to all lookups.
  • Attribute Modes:
    • [Env(Key = "FOO")] (direct key)
    • [Env(Key = "BAR", IsList = true)] (comma-separated list)
    • [Env(ListPrefix = "ITEM_")] (numbered list: ITEM_1, ITEM_2, ...)
    • [Env(MapPrefix = "MAP_")] (dictionary: MAP_key1=val1, MAP_key2=val2)
    • [Env(NestedPrefix = "DB_")] (nested object)
  • Supported Types: Primitives (string, int, bool, double, etc.), DateTime, TimeSpan, Guid, enums, nullable types, List<T>, T[], Dictionary<TKey,TValue>. Custom types can be supported via ITypeConverter.
  • Logging: Pass a custom logger (IEnvLogSink) or use an adapter for your framework.
  • Custom Type Converters: Implement ITypeConverter and register with TypeConverterRegistry.RegisterConverter() to handle custom string-to-type conversions.
  • Error Handling: Configure EnvConfig.ThrowOnConversionError (default false) to control behavior when type conversion fails. If true, exceptions are thrown; otherwise, errors are logged and default values are used.

๐Ÿ”ง Advanced Usage & Features (Continued)

Custom Type Converters

EnvoyConfig allows you to define and register custom converters for types that are not natively supported or when you need specific parsing logic.

  1. Implement ITypeConverter: Create a class that implements the EnvoyConfig.Conversion.ITypeConverter interface. The core method is object? Convert(string? value, Type targetType, IEnvLogSink? logger).

    // Example: A simple Point class and its converter
    public class Point { public int X { get; set; } public int Y { get; set; } }
    
    public class PointConverter : ITypeConverter
    {
        public object? Convert(string? value, Type targetType, IEnvLogSink? logger)
        {
            if (string.IsNullOrWhiteSpace(value)) return null;
            var parts = value.Split(',');
            if (parts.Length == 2 && int.TryParse(parts[0], out int x) && int.TryParse(parts[1], out int y))
            {
                return new Point { X = x, Y = y };
            }
            logger?.Log(EnvLogLevel.Error, $"Cannot convert '{value}' to Point.");
            return null;
        }
    }
    
  2. Register the Converter: Before loading your configuration, register an instance of your converter:

    using EnvoyConfig.Conversion;
    // ...
    TypeConverterRegistry.RegisterConverter(typeof(Point), new PointConverter());
    // ...
    // var config = EnvConfig.Load<YourConfigWithAPointProperty>();
    

Error Handling

Control how EnvoyConfig behaves when a type conversion from a string environment variable to a target property type fails:

  • EnvConfig.ThrowOnConversionError (static property):
    • false (Default): If a conversion fails (e.g., "abc" cannot be parsed as an int), EnvoyConfig logs an error (if a logger is provided) and the property is set to its default C# value (e.g., 0 for int, null for reference types).

    • true: If a conversion fails, EnvoyConfig will throw an InvalidOperationException detailing the conversion issue. This allows for immediate and strict error handling.

      // Example:
      EnvConfig.ThrowOnConversionError = true; // Optional: for stricter error handling
      try
      {
          // var config = EnvConfig.Load<MyConfig>();
      }
      catch (InvalidOperationException ex)
      {
          // Handle conversion errors
      }
      

๐Ÿ› ๏ธ Troubleshooting / FAQ

  • Type conversion errors: Check environment variable values and target property types. If EnvConfig.ThrowOnConversionError is false (default), check logs for details and verify if the property has its default C# value. If true, an exception will be thrown.
  • Missing env vars: Use Default attribute property or handle null/default values in your application logic.
  • Prefix confusion: Ensure GlobalPrefix and attribute keys/prefixes are set as intended.
  • Logging: Implement IEnvLogSink or use provided adapters for structured logs, especially to diagnose conversion issues when ThrowOnConversionError is false.

๐Ÿค Contributing

Contributions are welcome! Please open issues or PRs for bugs, features, or questions.

๐Ÿ“œ License

LGPL-3.0-or-later. See LICENSE.

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.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  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.
  • net8.0

    • No dependencies.

NuGet packages (3)

Showing the top 3 NuGet packages that depend on EnvoyConfig:

Package Downloads
EnvoyConfig.Adapters.Serilog

Package Description

EnvoyConfig.Adapters.NLog

Package Description

EnvoyConfig.Adapters.Microsoft

Package Description

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.0 538 6/25/2025
0.1.0-beta.108 125 6/24/2025
0.1.0-beta.96 129 6/22/2025
0.1.0-beta.81 188 6/15/2025
0.1.0-alpha.1 64 5/3/2025