Skip to content

Accessing Configuration in ASP.NET Core 6+ Startup

Problem Statement

In ASP.NET Core 6, Microsoft introduced a simplified project template that replaces the traditional Startup.cs class with a single Program.cs file using top-level statements. This change left many developers wondering how to access essential objects like IConfiguration and IHostEnvironment that were previously available through dependency injection in the Startup class constructor.

Solution Overview

The WebApplicationBuilder class provides direct access to configuration and environment objects. Here are the primary approaches to access these essential services:

1. Direct Access via WebApplicationBuilder

The WebApplication.CreateBuilder(args) method returns a WebApplicationBuilder instance that exposes both Configuration and Environment properties:

cs
var builder = WebApplication.CreateBuilder(args);

// Access configuration
ConfigurationManager configuration = builder.Configuration;

// Access environment
IWebHostEnvironment environment = builder.Environment;

// Example: Read connection string
var connectionString = builder.Configuration.GetConnectionString("Festify");

2. Access via Built Application

After building the application, you can also access these services from the WebApplication instance:

cs
var app = builder.Build();

// Access configuration
IConfiguration configuration = app.Configuration;

// Access environment
IWebHostEnvironment environment = app.Environment;

3. Configuration Binding to Strongly-Typed Classes

For better maintainability, bind configuration sections to strongly-typed classes:

cs
// In appsettings.json
{
  "ConnectionKeys": {
    "DefaultConnection": "your_connection_string"
  }
}

// Configuration class
public class ConnectionKeys
{
    public string DefaultConnection { get; set; }
}

// Program.cs registration
builder.Services.Configure<ConnectionKeys>(
    builder.Configuration.GetSection("ConnectionKeys"));

Practical Examples

Database Configuration

Here's how to configure Entity Framework Core with a connection string:

cs
var builder = WebApplication.CreateBuilder(args);

builder.Services.AddDbContext<FestifyContext>(options => 
    options.UseSqlServer(
        builder.Configuration.GetConnectionString("Festify")));
json
{
  "ConnectionStrings": {
    "Festify": "Server=localhost;Database=FestifyDB;Trusted_Connection=True;"
  }
}

Environment-Specific Configuration

cs
var builder = WebApplication.CreateBuilder(args);

// Add configuration sources
builder.Configuration
    .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
    .AddJsonFile($"appsettings.{builder.Environment.EnvironmentName}.json", optional: true)
    .AddEnvironmentVariables();

// Example usage
if (builder.Environment.IsDevelopment())
{
    // Development-specific setup
    builder.Services.AddDatabaseDeveloperPageExceptionFilter();
}

Worker Service Configuration

For worker services (non-web applications), use this pattern:

cs
IHost host = Host.CreateDefaultBuilder(args)
    .ConfigureServices((context, services) =>
    {
        var settings = context.Configuration.Get<AppSettings>();
        // Register services with settings
    })
    .Build();

Advanced Techniques

Custom Configuration Setup

For complex scenarios, you can manually configure the configuration builder:

cs
var configurationBuilder = new ConfigurationBuilder()
    .SetBasePath(Directory.GetCurrentDirectory())
    .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
    .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
    .AddEnvironmentVariables();

IConfiguration configuration = configurationBuilder.Build();

Static Access Pattern (Use with Caution)

WARNING

This approach bypasses dependency injection and can make testing more difficult. Use only when necessary.

cs
// Program.cs
partial class Program
{
    public static IConfiguration? Configuration { get; private set; }
}

// During configuration
var builder = WebApplication.CreateBuilder(args);
Configuration = builder.Configuration;

// In other classes
string connectionString = Program.Configuration.GetConnectionString("Default");

Best Practices

  1. Use dependency injection where possible instead of static access patterns
  2. Leverage strongly-typed configuration for better maintainability
  3. Follow the environment pattern for different deployment environments
  4. Keep sensitive data out of configuration files using environment variables or secret manager

Migration Tips

If you're migrating from earlier ASP.NET Core versions:

  • The Configuration property replaces the IConfiguration previously injected into Startup
  • The Environment property replaces IHostEnvironment/IWebHostEnvironment
  • Consider organizing your configuration code into extension methods for better readability

Conclusion

ASP.NET Core 6+ simplifies application configuration while maintaining all the power of previous versions. The WebApplicationBuilder provides straightforward access to configuration and environment information, and the patterns shown above will help you effectively manage your application settings in the new project structure.