Gnar.Enver.SourceGeneration 0.1.0-beta.3

This is a prerelease version of Gnar.Enver.SourceGeneration.
The owner has unlisted this package. This could mean that the package is deprecated, has security vulnerabilities or shouldn't be used anymore.
dotnet add package Gnar.Enver.SourceGeneration --version 0.1.0-beta.3
                    
NuGet\Install-Package Gnar.Enver.SourceGeneration -Version 0.1.0-beta.3
                    
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="Gnar.Enver.SourceGeneration" Version="0.1.0-beta.3" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Gnar.Enver.SourceGeneration" Version="0.1.0-beta.3" />
                    
Directory.Packages.props
<PackageReference Include="Gnar.Enver.SourceGeneration" />
                    
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 Gnar.Enver.SourceGeneration --version 0.1.0-beta.3
                    
#r "nuget: Gnar.Enver.SourceGeneration, 0.1.0-beta.3"
                    
#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 Gnar.Enver.SourceGeneration@0.1.0-beta.3
                    
#: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=Gnar.Enver.SourceGeneration&version=0.1.0-beta.3&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=Gnar.Enver.SourceGeneration&version=0.1.0-beta.3&prerelease
                    
Install as a Cake Tool

Enver.SourceGeneration

Attributes and a Roslyn source generator that bind .env values to strongly-typed config classes.

Part of the Enver family. See the main project README for the broader ecosystem.

Quick start

dotnet add package Gnar.Enver.SourceGeneration

Mark a partial type with [EnverBindable] and the generator emits a Bind family of static methods on it:

using Enver;
using Enver.SourceGeneration;

[EnverBindable]
public partial record DatabaseConfig(string Host, int Port)
{
    public bool UseSsl { get; init; } = true;
}

// Pick one:

// 1. Bind by loading a .env from the app directory.
var cfg = DatabaseConfig.BindFromAppDirectory();

// 2. Bind by loading a .env from the working directory.
var cfg = DatabaseConfig.BindFromWorkingDirectory();

// 3. Bind by loading a specific file.
var cfg = DatabaseConfig.BindFromFile("/etc/myapp/.env");

// 4. Bind from an existing IEnvReader (EnvCollection, Environment.Variables,
//    configuration.AsEnvReader(), …)
var cfg = DatabaseConfig.Bind(values);

By default, property names map to UPPER_SNAKE_CASE keys (Host → HOST, UseSsl → USE_SSL).

Generated surface

For a self-bindable type ([EnverBindable] on the type itself), the generator emits three static factories plus a streaming Binder:

public partial record DatabaseConfig
{
    public static DatabaseConfig Bind(IEnvReader reader);
    public static DatabaseConfig BindFromAppDirectory(
        string fileName = ".env",
        string? variant = null,
        int maxAncestors = 0,
        bool throwIfMissing = false,
        EnvParseOptions parseOptions = default);
    public static DatabaseConfig BindFromWorkingDirectory(
        string fileName = ".env",
        string? variant = null,
        int maxAncestors = 0,
        bool throwIfMissing = false,
        EnvParseOptions parseOptions = default);
    public static DatabaseConfig BindFromFile(
        string path,
        bool throwIfMissing = true,
        EnvParseOptions parseOptions = default);

    public sealed partial class Binder : EnvParser
    {
        public DatabaseConfig Build();
    }
}

The same surface is generated on an external host ([EnverBindable<T>]), with method names suffixed by the target's simple type name (Configs.BindCacheConfig(...) / Configs.CacheConfigBinder). See External host below.

Naming and prefix: [EnverConfig]

[EnverConfig] configures how member names map to keys. It does not trigger generation on its own. Pair it with [EnverBindable] on the same type:

[EnverBindable]
[EnverConfig("DB", KeyNaming = EnverKeyNamingConvention.UpperSnakeCase)]
public partial record DatabaseConfig(string Host, int Port);
// Reads DB_HOST and DB_PORT.

Naming conventions:

  • UpperSnakeCase (default): HostName → HOST_NAME
  • SnakeCase: HostName → host_name
  • PreserveOriginal: HostName → HostName
  • Inherit: use the nearest enclosing [EnverConfig] (falls back to UpperSnakeCase)

Prefixes and names set with [EnverKey] are not passed through the KeyNaming convention.

Per-member overrides: [EnverKey]

[EnverBindable]
[EnverConfig("APP")]
public partial class AppConfig
{
    // Map to APP_CUSTOM_NAME
    [EnverKey("CUSTOM_NAME")]
    public string Name { get; init; } = "";

    // Map to GLOBAL_SETTING
    [EnverKey(IgnorePrefix = true)]
    public string GlobalSetting { get; init; } = "";

    // Force optional
    [EnverKey(Required = EnverRequirementBehavior.Optional)]
    public int Port { get; init; }

    // Force required
    [EnverKey(Required = EnverRequirementBehavior.Required)]
    public string? Tag { get; init; }
}

Records: when annotating a primary-constructor parameter, use the [property: EnverKey(...)] target so the attribute lands on the generated property rather than the parameter.

Other attributes

Attribute Effect
[EnverIgnore] Skip a member that would otherwise be bound.
[EnverUri(UriKind)] Specify UriKind for Uri members (default Absolute).
[EnverFormatProvider(type, memberName)] Point at a static IFormatProvider member used when parsing numbers, dates, etc. Applies type-wide when placed on the class/struct; per-member when placed on a field/property.

Required vs. optional

Each member is classified as required, optional, or with-default. The generator infers from C# signals, in order:

  1. required modifier → required
  2. Nullable value or reference type → optional
  3. Property initializer → optional with default
  4. Non-nullable type → required
  5. Reference type under #nullable disable → optional

Required members that are missing throw EnverException at Bind() time with the failing key. Optional members fall back to default(T) or the declared initializer.

Override the inferred classification with [EnverKey(Required = EnverRequirementBehavior.Required | .Optional)].

External host: [EnverBindable<T>]

Generate binders on a separate partial class:

public sealed record CacheConfig(int Ttl, string Region);

[EnverBindable<CacheConfig>]
public partial class Configs;

The static factories on the host are suffixed with the target's name, and the streaming binder lives alongside them:

var cfg = Configs.BindCacheConfig(reader);
var cfg = Configs.BindCacheConfigFromAppDirectory();
var binder = new Configs.CacheConfigBinder();

[EnverBindable<T>] is repeatable. One host can have binders for several targets.

Custom parsing

The generated Binder derives from EnvParser, so you can control parsing directly.

Binding directly to UTF-8 content:

var binder = new DatabaseConfig.Binder();
binder.Parse(
    """
    HOST=db.internal
    URL="postgres://${HOST}:5432"
    """u8
);
var cfg = binder.Build();

Supported types

  • string, bool, Guid, Uri
  • int, long, and any numeric type implementing INumber<T> / IParsable<T> (including 0x / 0b prefix support)
  • Enums
  • Any IUtf8SpanParsable<T>, ISpanParsable<T>, or IParsable<T> (such as IPAddress, IPNetwork, Version)

See the main project README for the full list.

License

MIT.

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 is compatible.  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 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