To use varlock with C#, install the standalone binary and run your app under varlock run. It loads and validates your env, then injects it into the process.
Add @generateCsharpEnv to your schema to generate a small, self-contained class: a typed Env with init-only properties, a static Load() that parses the injected __VARLOCK_ENV blob, and a SensitiveKeys set.
# @generateCsharpEnv(path=Env.cs)The file is regenerated automatically on varlock load and varlock run, or explicitly with varlock codegen. Requires .NET 6+ (uses System.Text.Json from the BCL; no extra NuGet package). Optional namespace= and class= set the C# namespace and class name (default: no namespace, class Env). Property names are PascalCase (DB_HOST → DbHost).
Reading values
Section titled “Reading values”Call Load() once, then read properties off the object. Required fields are the plain type, optional ones are nullable (long?, bool?, string?):
var e = Env.Load(); // call once, hold or pass `e` aroundvar host = e.DbHost; // string (required field)if (e.DbPort is long port) // long? (optional field){ Console.WriteLine($"{host}:{port}");}varlock run -- dotnet runLoad() throws a clear error if __VARLOCK_ENV is missing (e.g. you forgot varlock run) or if a required key is absent.
Sharing one instance
Section titled “Sharing one instance”Every Load() call re-parses the blob. To avoid reloading, register the loaded instance in DI or expose it from a static holder:
// Program.cs / startupbuilder.Services.AddSingleton(Env.Load());
// elsewhere, inject Envpublic class MyService(Env env){ public void Run() => Console.WriteLine(env.DbPort);}No DI? A tiny static holder works:
public static class Config{ public static Env Values { get; } = Env.Load();}
// elsewhere: Config.Values.DbPort (long?)