EnvVault 1.0.3
dotnet add package EnvVault --version 1.0.3
NuGet\Install-Package EnvVault -Version 1.0.3
<PackageReference Include="EnvVault" Version="1.0.3" />
<PackageVersion Include="EnvVault" Version="1.0.3" />
<PackageReference Include="EnvVault" />
paket add EnvVault --version 1.0.3
#r "nuget: EnvVault, 1.0.3"
#:package EnvVault@1.0.3
#addin nuget:?package=EnvVault&version=1.0.3
#tool nuget:?package=EnvVault&version=1.0.3
EnvVault
EnvVault is a high-performance, type-safe environment variable binder for .NET 10. It eliminates manual string parsing and provides a declarative, attribute-based way to manage application configuration — optimized for Docker, Kubernetes, and AWS Lambda.
Note: Native AOT is not supported in v1; source generator support is planned.
Why this instead of IConfiguration? Unlike IConfiguration, EnvVault has zero dependencies and no setup pipeline: no builders, no providers, no host required.
Features
- Automatic Type Conversion — supports all types implementing
IParsable<T>(int,bool,Guid,TimeSpan, etc.), plusstringpassthroughs andenumtypes. - Fail-Fast Validation — throws a detailed exception at startup if configuration is missing or invalid. Your container will never run in a broken state due to a typo.
- Error Aggregation — all missing / malformed variables are collected and reported in a single exception, not one at a time.
- Attribute-Based Mapping — declare your requirements with standard C# records or plain classes.
- Performance Optimized — type metadata is scanned once and cached in a
FrozenDictionary. Subsequent bindings reuse cached metadata and avoid re-scanning type information, minimizing reflection overhead. - Testable by Design — inject an
IEnvironmentVariableProviderin unit tests instead of mutating process environment variables.
Installation
dotnet add package EnvVault
Quick Start
1. Define your configuration record
using System;
using EnvVault.Attributes;
public record ApiConfig(
[Env("API_PORT", Required = true)] int Port,
[Env("API_KEY", Required = true)] string Key,
[Env("TIMEOUT_MS", Default = "00:00:30")] TimeSpan Timeout,
[Env("IS_ENABLED", Default = "true")] bool IsEnabled
);
Note:
Defaultis always astring(environment variables are strings). The value is parsed through the same pipeline as a live variable.
2. Bind at startup
using System;
using EnvVault;
using EnvVault.Exceptions;
try
{
ApiConfig config = EnvBinder.Map<ApiConfig>();
Console.WriteLine($"Server starting on port: {config.Port}");
}
catch (EnvVaultException ex)
{
// ex.Errors lists every problem found — not just the first one
Console.Error.WriteLine($"Configuration error:{Environment.NewLine}{ex.Message}");
Environment.Exit(1);
}
Advanced Usage
Supported types
| Category | Examples |
|---|---|
| Strings | string |
| Integers | int, long, short, byte, uint, … |
| Floating point | double, float, decimal |
| Date & time | DateTime, DateTimeOffset, DateOnly, TimeOnly, TimeSpan |
| Other primitives | bool, Guid, Uri |
| Enums | Any enum (case-insensitive) |
| Nullable wrappers | int?, Guid?, MyEnum?, … |
| Custom types | Any type implementing IParsable<T> |
Required vs Optional
using EnvVault.Attributes;
public record DbConfig(
[Env("DB_HOST", Required = true)] string Host, // exception if absent
[Env("DB_PORT", Default = "5432")] int Port, // falls back to "5432"
[Env("DB_NAME")] string? Name // null if absent
);
Note: Empty or whitespace-only strings are treated as missing values. Required variables will fail, optional values fall back to defaults.
Plain class support
Records are recommended, but plain classes with settable properties work too:
using EnvVault.Attributes;
public class DbConfig
{
[Env("DB_HOST", Required = true)]
public string Host { get; set; } = string.Empty;
[Env("DB_PORT", Default = "5432")]
public int Port { get; set; }
}
Unit testing
Note:
IEnvironmentVariableProvideris public to enable deterministic tests.
using System;
using System.Collections.Generic;
using EnvVault;
// No process environment mutation needed
sealed class InMemoryEnvironment : IEnvironmentVariableProvider
{
private readonly IReadOnlyDictionary<string, string?> _values;
public InMemoryEnvironment(IReadOnlyDictionary<string, string?> values)
{
_values = values;
}
public string? Get(string key)
{
ArgumentNullException.ThrowIfNull(key);
return _values.GetValueOrDefault(key);
}
}
IEnvironmentVariableProvider provider = new InMemoryEnvironment(new Dictionary<string, string?>
{
["API_PORT"] = "8080",
["API_KEY"] = "test-key",
});
ApiConfig config = EnvBinder.Map<ApiConfig>(provider);
Technical Notes
- Uses
IParsable<T>(introduced in .NET 7) for zero-hardcoded-type conversion. FrozenDictionary(introduced in .NET 8) powers the reflection cache — reads are as fast as a regular dictionary with no locking overhead.- The
[RequiresUnreferencedCode]annotation is applied toEnvBinder.Mapto be honest with trimming / AOT tooling. Full source-generator support is a planned future milestone.
Limitations (v1)
- Hierarchical binding (e.g.
DB__HOSTto nested objects) is not supported in v1.
Roadmap
- Source generator binding for Native AOT compatibility.
- Hierarchical binding for nested objects.
License
MIT
| Product | Versions 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. |
-
net10.0
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.