This episode covers .NET application settings: appsettings.json and environment variables, the options pattern with binding to POCOs, secrets management and multi-environment configuration, and the role of IHostEnvironment in the .NET Generic Host.

Production applications almost never run with hardcoded values. Database connection strings differ between development, staging, and production — and changing them must not mean recompiling the code. This is where configuration comes in.
The .NET configuration system is a layered model: values can come from JSON, environment variables, or the command line, and they are merged in a specific order. The most specific value wins.
Episode 8 covers appsettings.json, environment variables, the options pattern, secrets management, and the Generic Host that underpins all modern ASP.NET Core applications.
The appsettings.json file stores default configuration. When the application runs, the environment variables provider overrides its values — a pattern that's very useful in containers:
{
"ConnectionStrings": {
"Default": "Host=localhost;Database=toko;Username=postgres;Password=secret"
},
"Email": {
"Sender": "no-reply@contoh.id",
"SmtpPort": 587
},
"AllowedHosts": "*"
}The configuration above is read automatically when the application starts. To override Email:SmtpPort from an environment variable, set Email__SmtpPort=465 — the double __ separator in environment variables represents the colon in the JSON hierarchy.
Capturing configuration directly into a POCO makes your code resistant to typos in key names. This is the options pattern:
class EmailOptions
{
public string Sender { get; set; } = "";
public int SmtpPort { get; set; }
}
var builder = Host.CreateApplicationBuilder(args);
builder.Services.Configure<EmailOptions>(
builder.Configuration.GetSection("Email"));
var app = builder.Build();
app.Run();GetSection("Email") reads the Email subtree from JSON and maps it to the class properties. Now you can read configuration with a safe type instead of a raw string.
Options are accessed by injecting IOptions<T> into a class:
class EmailSender
{
private readonly EmailOptions _options;
public EmailSender(IOptions<EmailOptions> options)
{
_options = options.Value;
}
public void Kirim()
{
Console.WriteLine($"Mengirim dari {_options.Sender} port {_options.SmtpPort}");
}
}This pattern makes settings easy to test — you just replace IOptions<EmailOptions> with a different value during testing.
.NET has a built-in concept of environments: Development, Staging, and Production. The application loads appsettings.json, then overrides it with appsettings.{Environment}.json. For local secrets, use user-secrets, which are stored outside the project:
dotnet user-secrets init
dotnet user-secrets set "ConnectionStrings:Default" "Host=localhost;Database=toko;Username=postgres;Password=rahasia"The dotnet user-secrets set command stores the value in the user profile, not in the repository. This secrets.json file is never committed, so passwords don't leak into Git.
The environment is selected through the ASPNETCORE_ENVIRONMENT variable:
ASPNETCORE_ENVIRONMENT=Production dotnet runThe command above loads the appsettings.Production.json file if present. Environment names can be checked in code through IHostEnvironment.
The Generic Host unifies configuration, logging, dependency injection, and the application lifecycle in one pipeline. When you need an environment value inside the code:
var builder = Host.CreateApplicationBuilder(args);
var environment = builder.Environment;
if (environment.IsDevelopment())
{
builder.Services.AddDeveloperExceptionPage();
}
Console.WriteLine($"Environment: {environment.EnvironmentName}");
Console.WriteLine($"Root path: {environment.ContentRootPath}");IHostEnvironment.EnvironmentName returns the active environment name, and helpers like IsDevelopment() make conditional code clear. This also lets us add different configuration for each environment.
Key takeaways:
ASPNETCORE_ENVIRONMENT selects the per-environment configuration file.In the next episode 9 we touch databases: data access and persistence — Entity Framework Core and DbContext, CRUD operations, migrations and relationships, querying with LINQ and raw SQL, and database providers such as SQL Server, PostgreSQL, and SQLite.