Chapter 10: Configuring an ASP.NET Core application
This introduction explains why ASP.NET Core configuration lets applications change settings at deployment time and previews configuration providers, strongly typed options, and hosting environments.
After this chapter you will be able to
- Deployment-time configuration purpose. Explain why an application uses configuration: to tweak settings when it is deployed without recompiling the application.
- Configuration source aggregation. Describe that ASP.NET Core can load settings from JSON files, environment variables, and command-line arguments, combining them into one unified configuration object.
- Options and environment configuration. Describe that configuration can be bound to strongly typed options objects—POCO classes injectable into services—to encapsulate feature settings, and that hosting environments allow an app to load different configuration and vary behavior for situations such as development and production.
- Configuration settings and secrets. Explain configuration as external parameters that control an application's behavior at runtime, and distinguish ordinary settings from secrets. State that secrets are sensitive settings such as passwords, third-party API keys, and connection strings.
- Externalized configuration rationale. Justify moving settings and secrets out of application code so they can be changed at deployment time without recompiling. Explain that externalizing secrets also reduces the risk of exposing them through source control or extracting them from a compiled application.
- Configuration providers and sources. Describe configuration providers as components that load string key-value pairs, and state that an ASP.NET Core application can use multiple providers. Identify that values can come from files in formats such as JSON, XML, or YAML, as well as environment variables, command-line arguments, databases, remote services, or a custom provider.
- ConfigurationManager roles. Explain that ConfigurationManager simplifies configuration by implementing both IConfigurationBuilder, which describes how configuration is constructed, and IConfigurationRoot, which holds the resulting values.
- Configuration provider layering. Describe how IConfigurationProviders load key-value pairs from sources such as JSON files and environment variables when added to ConfigurationManager, producing a combined IConfiguration whose values can be overridden by later configuration sources.
- Default configuration providers. Describe the default providers that WebApplicationBuilder adds to its ConfigurationManager and the kinds of settings they load. State that Configuration is available from both WebApplicationBuilder and WebApplication and refers to the same ConfigurationManager instance.
- Custom provider registration. Explain how to customize configuration sources by adding a provider such as AddJsonFile() in Program.cs or by clearing the default sources first. Describe how optional: true lets a missing JSON file be skipped rather than causing FileNotFoundException.
- Configuration value lookup. Describe how IConfiguration exposes settings as string key-value pairs, including using colon-delimited keys for nested sections and GetSection() to reset the namespace to a section. State that a missing key returns null and that string-key access is mainly useful during Program.cs setup rather than as the preferred general application pattern.
- Provider ordering and overrides. Explain that configuration providers are added in order to ConfigurationManager, and that a value from a later provider overwrites an earlier value when both use the same configuration key.
- Secret storage strategy. Explain why passwords, connection strings, and API keys should not be stored in appsettings.json or committed to source control, and identify environment variables and User Secrets as approaches that keep them outside the project folder.
- Environment variable configuration. Describe how environment variables become configuration key-value pairs, including how colon or double-underscore names represent hierarchical sections and how these values override appsettings.json defaults at runtime.
- Development User Secrets setup. Describe User Secrets as per-application, plain-text development configuration stored outside the project tree, and trace the role of the UserSecretsId, secrets.json, and AddUserSecrets/Program marker in locating and loading those values.
- Runtime configuration reloading. Explain how ASP.NET Core can update configuration after a file is edited without recompiling or restarting the application. Describe the production logging example: temporarily raising logging from warning/error to Debug for diagnosis, then lowering it again.
- File provider reload setup. Describe how to enable reload for a file-based configuration provider by using an Add*File overload with reloadOnChange set to true. State that ASP.NET Core monitors the file system and can rebuild IConfiguration when the file changes.
- Strongly typed settings benefits. Explain why strongly typed settings are preferred over reading IConfiguration with string keys. Describe how options classes avoid typo-prone string lookups and manual string conversion while improving type safety, IntelliSense, and testability.
- Feature-scoped options classes. Describe an options class as a POCO that represents a small, related collection of configuration settings for one application feature. Explain how separate configuration sections, such as MapSettings and AppDisplaySettings, correspond to different feature-specific settings objects.
- Configuration binding process. Describe configuration binding as the process in which the ASP.NET Core configuration binder takes a collection of configuration values and creates or populates a strongly typed options object. Relate it to deserialization or model binding without treating it as manual string parsing.
- Strongly typed options benefits. Explain how POCO options classes provide explicit, strongly typed configuration dependencies that support the single-responsibility principle and simplify testing compared with passing IConfiguration.
- IOptions registration and lifetime. Trace how Configure<T> registers configuration for IOptions<T>: each call creates configuration work that binds a configuration section into a T POCO, multiple calls can contribute to the final object, and IOptions<T>.Value exposes that object through a singleton DI service. Explain that binding occurs on the first request and does not refresh the POCO when configuration reloads.
- Options snapshot reload behavior. Distinguish IOptions<T> from IOptionsSnapshot<T> by explaining when each creates its strongly typed options object and how configuration changes become visible.
- Snapshot service lifetime. Describe why IOptionsSnapshot<T> can be injected into scoped services during requests but must not be injected into a singleton service, and name IOptionsMonitor<T> as the similar singleton-friendly alternative mentioned here.
- Options class construction rules. Describe why an options class must be nonabstract and have a public parameterless constructor for automatic binding. Explain that the binder uses reflection to create the options instance.
- Bindable property requirements. Explain which properties the binder can bind on an options class: they must be public, have a getter, not be indexers, and have a setter unless a complex property already has a non-null value.
- Direct settings injection. Describe how to bind a configuration section to a strongly typed settings object, register that object with the DI container, and inject the settings type directly into a handler or service instead of injecting IOptions<T>.
- Direct binding trade-offs. Explain why direct settings injection can simplify consumers, especially reusable libraries, and state that it loses strongly typed reload support and some advanced IOptions capabilities unless additional work is done.
- Purpose of hosting environments. Explain why an ASP.NET Core application may use different configuration values in development and production, such as different database connection strings and logging levels.
- Environment configuration tasks. Describe the three environment-related tasks covered in this section: identifying the current hosting environment, loading configuration values for it, and setting the environment on a machine.
- Hosting environment identification. Explain how WebApplicationBuilder determines the current hosting environment from environment variables and exposes it through WebApplicationBuilder.Environment as an IHostEnvironment.
- Environment names and checks. Describe the conventional Development, Staging, and Production environment names, and explain why IHostEnvironment helper methods should be used to test them instead of directly comparing EnvironmentName strings.
- Environment-specific JSON configuration. Describe the pattern of loading an optional appsettings.ENVIRONMENT.json file after the global appsettings.json file. Explain that the file chosen depends on EnvironmentName and that matching keys in the environment-specific file override global values.
- Conditional configuration providers. Explain that EnvironmentName is established early during application bootstrapping, so it can determine which configuration providers are added before IConfiguration is built. Describe using IHostEnvironment to add User Secrets in development but a provider such as Azure Key Vault in production.
- Hosting environment default. Explain how ASP.NET Core chooses its hosting environment at startup, including the default when ASPNETCORE_ENVIRONMENT is absent.
- Launch profile configuration. Describe how launchSettings.json profiles set project-local environment variables and choose how an application runs during local development.
What it builds on
- Using services from the DI container (chapter 8) · The idea that services can receive dependencies from the DI container.
- Program.cs file: Defining your application (chapter 3) · The application definition in Program.cs, where ConfigurationManager is used.
- Using dependency injection in ASP.NET Core (chapter 8) · The ASP.NET Core dependency-injection container and injecting dependencies into application code.
- Singleton: There can be only one (chapter 9) · The singleton lifetime concept used by IOptions<T>.
- Scoped: Let’s stick together (chapter 9) · Scoped services are created within a scope such as a request.
- Keeping an eye out for captive dependencies (chapter 9) · A singleton holding a shorter-lived service creates a captive dependency.
- Registering services using objects and lambdas (chapter 9) · Registering services with objects and lambdas.
- Viewing exceptions in development: DeveloperExceptionPage (chapter 4) · DeveloperExceptionPage and its use during development.
Section by section
Introduction
This introduction explains why ASP.NET Core configuration lets applications change settings at deployment time and previews configuration providers, strongly typed options, and hosting environments.
- Deployment-time configuration purpose: Explain why an application uses configuration: to tweak settings when it is deployed without recompiling the application.
Why it matters: Configuration separates deployable application behavior from values that may need to change between deployments. - Configuration source aggregation: Describe that ASP.NET Core can load settings from JSON files, environment variables, and command-line arguments, combining them into one unified configuration object.
Why it matters: A unified configuration object lets an app draw settings from sources suited to different deployment needs. - Options and environment configuration: Describe that configuration can be bound to strongly typed options objects—POCO classes injectable into services—to encapsulate feature settings, and that hosting environments allow an app to load different configuration and vary behavior for situations such as development and production.
Why it matters: Typed settings make feature configuration easier to use in services, while environments let one application behave appropriately in development and production.
Key terms: configuration, deploy time, recompile, configuration providers, JSON, environment variables, command-line arguments, configuration object, strongly typed options objects, POCO
10.1 Introducing the ASP.NET Core configuration model
This section defines ASP.NET Core configuration, explains why settings and secrets should live outside compiled code, and introduces providers, overrides, and strongly typed binding.
- Configuration settings and secrets: Explain configuration as external parameters that control an application's behavior at runtime, and distinguish ordinary settings from secrets. State that secrets are sensitive settings such as passwords, third-party API keys, and connection strings.
Why it matters: This distinction helps you decide what application values must be configurable and which need extra protection. - Externalized configuration rationale: Justify moving settings and secrets out of application code so they can be changed at deployment time without recompiling. Explain that externalizing secrets also reduces the risk of exposing them through source control or extracting them from a compiled application.
Why it matters: External configuration makes deployments flexible and avoids accidentally publishing sensitive credentials. - Configuration providers and sources: Describe configuration providers as components that load string key-value pairs, and state that an ASP.NET Core application can use multiple providers. Identify that values can come from files in formats such as JSON, XML, or YAML, as well as environment variables, command-line arguments, databases, remote services, or a custom provider.
Why it matters: Providers let an application obtain configuration from sources appropriate to local development, deployment, and operations. - Provider override and typed binding: Describe that later configuration providers can overwrite values supplied by earlier providers. Explain that string key-value configuration can also be bound to POCO settings classes, providing strongly typed configuration that groups feature settings and supports unit testing.
Why it matters: Overrides allow deployment-specific values to replace defaults, while typed settings make related configuration easier to use and test.
Key terms: configuration, settings, secrets, connection string, API key, externalize, deploy time, source control, compiled code, configuration providers
10.2 Building a configuration object for your app
This section introduces how ASP.NET Core assembles application configuration from providers and how to organize values in appsettings.json.
- ConfigurationManager roles: Explain that ConfigurationManager simplifies configuration by implementing both IConfigurationBuilder, which describes how configuration is constructed, and IConfigurationRoot, which holds the resulting values.
Why it matters: This explains how an app both defines configuration sources and accesses the combined configuration they produce. - Configuration provider layering: Describe how IConfigurationProviders load key-value pairs from sources such as JSON files and environment variables when added to ConfigurationManager, producing a combined IConfiguration whose values can be overridden by later configuration sources.
Why it matters: Provider layering lets one application use sensible defaults while changing settings for a particular machine, environment, or deployment. - appsettings.json organization: Describe appsettings.json as a common default configuration file and explain that related settings can be grouped in nested JSON objects, creating configuration sections such as MapSettings and DefaultLocation for later binding to a POCO.
Why it matters: A clear nested configuration structure keeps related settings together and supports strongly typed settings later in the chapter. - Configuration value safety: State that appsettings.json must not contain sensitive values such as passwords, API keys, or connection strings, and describe that configuration providers store loaded values internally as strings while configuration keys are case-insensitive in the final app configuration.
Why it matters: Keeping secrets out of ordinary configuration files avoids exposing credentials, and knowing the key and value behavior prevents confusing configuration collisions.
Key terms: ConfigurationManager, IConfigurationBuilder, IConfigurationRoot, IConfiguration, IConfigurationProvider, key-value pairs, configuration providers, appsettings.json, configuration section, MapSettings
10.2.1 Adding a configuration provider in Program.cs
This section explains how WebApplicationBuilder creates and exposes configuration, how to add or replace configuration providers, and how to read configuration values through IConfiguration.
- Default configuration providers: Describe the default providers that WebApplicationBuilder adds to its ConfigurationManager and the kinds of settings they load. State that Configuration is available from both WebApplicationBuilder and WebApplication and refers to the same ConfigurationManager instance.
Why it matters: Knowing the default sources tells you where an ASP.NET Core app obtains settings before you add any custom configuration. - Custom provider registration: Explain how to customize configuration sources by adding a provider such as AddJsonFile() in Program.cs or by clearing the default sources first. Describe how optional: true lets a missing JSON file be skipped rather than causing FileNotFoundException.
Why it matters: Custom providers let an application load settings from the sources appropriate for its deployment and avoid failures for deliberately optional files. - ConfigurationManager access and binding: Explain that ConfigurationManager immediately incorporates values when a provider is added because it is both the builder and final IConfigurationRoot in .NET 6 and later. Describe that it is registered in DI as IConfiguration, so it can be injected into services and endpoint handlers.
Why it matters: This explains why configuration is ready to use during app setup and how application code can receive it through dependency injection. - Configuration value lookup: Describe how IConfiguration exposes settings as string key-value pairs, including using colon-delimited keys for nested sections and GetSection() to reset the namespace to a section. State that a missing key returns null and that string-key access is mainly useful during Program.cs setup rather than as the preferred general application pattern.
Why it matters: Reading the correct setting or section is necessary to configure application components such as database connections.
Key terms: WebApplicationBuilder, ConfigurationManager, Configuration, JSON file provider, User Secrets, environment variables, configuration provider, AddJsonFile, optional, FileNotFoundException
10.2.2 Using multiple providers to override configuration values
This section explains how multiple configuration providers combine into one IConfiguration and why providers added later override earlier values with the same key.
- Provider ordering and overrides: Explain that configuration providers are added in order to ConfigurationManager, and that a value from a later provider overwrites an earlier value when both use the same configuration key.
Why it matters: Provider order determines which configuration value your application actually uses. - Layered configuration aggregation: Describe how several providers contribute unique settings to a single IConfiguration while later providers replace only overlapping keys. Explain why this lets an application collect configuration from different sources, including sources appropriate for sensitive values.
Why it matters: Layering lets you keep a cohesive set of application settings while choosing suitable sources for different kinds of values.
Key terms: ConfigurationManager, configuration provider, IConfiguration, configuration key, overwrite, appsettings.json, environment variables, connection strings
10.2.3 Storing configuration secrets safely
This section explains how to keep sensitive configuration out of source control by using environment variables in production and User Secrets during local development.
- Secret storage strategy: Explain why passwords, connection strings, and API keys should not be stored in appsettings.json or committed to source control, and identify environment variables and User Secrets as approaches that keep them outside the project folder.
Why it matters: Keeping secrets out of source control reduces the risk of accidentally exposing credentials. - Environment variable configuration: Describe how environment variables become configuration key-value pairs, including how colon or double-underscore names represent hierarchical sections and how these values override appsettings.json defaults at runtime.
Why it matters: Environment variables let a deployed server or container supply its own sensitive values without changing the application files. - Development User Secrets setup: Describe User Secrets as per-application, plain-text development configuration stored outside the project tree, and trace the role of the UserSecretsId, secrets.json, and AddUserSecrets/Program marker in locating and loading those values.
Why it matters: User Secrets allow each local application to use different sensitive settings without placing them in its project or globally affecting other apps.
Key terms: appsettings.json, source control, environment variables, User Secrets, Azure Key Vault, AddEnvironmentVariables, ConfigurationManager, IConfiguration, MapSettings:MaxNumberOfPoints, MapSettings__MaxNumberOfPoints
10.2.4 Reloading configuration values when they change
This section explains how file-based configuration can reload automatically when its source file changes, avoiding application recompilation or restart.
- Runtime configuration reloading: Explain how ASP.NET Core can update configuration after a file is edited without recompiling or restarting the application. Describe the production logging example: temporarily raising logging from warning/error to Debug for diagnosis, then lowering it again.
Why it matters: Runtime reload lets you diagnose or tune a running application without interrupting its ability to serve requests. - File provider reload setup: Describe how to enable reload for a file-based configuration provider by using an Add*File overload with reloadOnChange set to true. State that ASP.NET Core monitors the file system and can rebuild IConfiguration when the file changes.
Why it matters: Knowing where reloadOnChange is configured lets you opt in when adding file sources manually. - Reloading defaults and limits: Distinguish file-based providers, which generally support reloading, from providers such as environment variables, which generally do not. State that WebApplicationBuilder already configures appsettings.json with reloadOnChange:true by default, but file watching has overhead and watching thousands of files can cause problems.
Why it matters: This helps you retain the useful defaults while avoiding incorrect assumptions and excessive file watchers.
Key terms: configuration reloading, appsettings.json, IConfiguration, Debug, Warning, Error, Add*File, reloadOnChange, ConfigurationManager, file-based configuration provider
10.3 Using strongly typed settings with the options pattern
This section introduces the options pattern as ASP.NET Core’s preferred approach for binding related configuration values into strongly typed POCO settings objects.
- Strongly typed settings benefits: Explain why strongly typed settings are preferred over reading IConfiguration with string keys. Describe how options classes avoid typo-prone string lookups and manual string conversion while improving type safety, IntelliSense, and testability.
Why it matters: Strongly typed settings make configuration code safer, clearer, and easier to test. - Feature-scoped options classes: Describe an options class as a POCO that represents a small, related collection of configuration settings for one application feature. Explain how separate configuration sections, such as MapSettings and AppDisplaySettings, correspond to different feature-specific settings objects.
Why it matters: Grouping related settings by feature keeps configuration and the code that consumes it organized. - Configuration binding process: Describe configuration binding as the process in which the ASP.NET Core configuration binder takes a collection of configuration values and creates or populates a strongly typed options object. Relate it to deserialization or model binding without treating it as manual string parsing.
Why it matters: Binding is the mechanism that turns configuration data into the typed objects application code can use.
Key terms: strongly typed settings, IConfiguration, options pattern, POCO, options class, MapSettings, AppDisplaySettings, configuration section, configuration binder, binding
10.3.1 Introducing the IOptions interface
This section introduces IOptions<T> for registering, binding, and injecting strongly typed configuration settings, including its singleton and reload limitations.
- Strongly typed options benefits: Explain how POCO options classes provide explicit, strongly typed configuration dependencies that support the single-responsibility principle and simplify testing compared with passing IConfiguration.
Why it matters: Options classes let a service depend only on the settings it needs instead of on the whole configuration system. - Options class binding requirements: Describe the requirements and binding behavior of an options class: it must be nonabstract with a public parameterless constructor, and binding sets its public properties from matching configuration values or sections, including complex nested properties.
Why it matters: Knowing what the binder can construct and populate helps you shape settings classes that bind automatically. - IOptions registration and lifetime: Trace how Configure<T> registers configuration for IOptions<T>: each call creates configuration work that binds a configuration section into a T POCO, multiple calls can contribute to the final object, and IOptions<T>.Value exposes that object through a singleton DI service. Explain that binding occurs on the first request and does not refresh the POCO when configuration reloads.
Why it matters: This explains both how to inject typed settings correctly and why IOptions<T> is unsuitable when a service must see configuration changes.
Key terms: strongly typed settings, POCO options class, IConfiguration, single-responsibility principle, SRP, binding, options class, public parameterless constructor, public properties, ConfigurationSection
10.3.2 Reloading strongly typed options with IOptionsSnapshot
This section explains how IOptionsSnapshot<T> reloads strongly typed configuration per request, and the lifetime and performance trade-offs of using it instead of IOptions<T>.
- Options snapshot reload behavior: Distinguish IOptions<T> from IOptionsSnapshot<T> by explaining when each creates its strongly typed options object and how configuration changes become visible.
Why it matters: Choosing the correct options interface determines whether a service continues using its original settings or sees updated configuration. - Snapshot service lifetime: Describe why IOptionsSnapshot<T> can be injected into scoped services during requests but must not be injected into a singleton service, and name IOptionsMonitor<T> as the similar singleton-friendly alternative mentioned here.
Why it matters: Respecting the snapshot service lifetime avoids creating a captive dependency while still allowing configuration to be refreshed where appropriate. - Reloading cost trade-off: Justify using IOptionsSnapshot<T> only where refreshed settings are worth the cost, because it rebinds and reconfigures the options object on every request.
Why it matters: Automatic configuration refresh can be convenient, but unnecessary per-request work can reduce application performance.
Key terms: IOptions<T>, IOptionsSnapshot<T>, POCO options object, IConfiguration, AppDisplaySettings, scoped service, singleton service, captive dependency, IOptionsMonitor<T>, rebinding
10.3.3 Designing your options classes for automatic binding
This section explains how to design POCO options classes so the configuration binder can instantiate them and bind their properties automatically.
- Options class construction rules: Describe why an options class must be nonabstract and have a public parameterless constructor for automatic binding. Explain that the binder uses reflection to create the options instance.
Why it matters: If the binder cannot create your options object, none of its configuration values can be populated. - Bindable property requirements: Explain which properties the binder can bind on an options class: they must be public, have a getter, not be indexers, and have a setter unless a complex property already has a non-null value.
Why it matters: Knowing the property rules helps you diagnose why a configuration value did not appear in a strongly typed settings object. - Collection interface binding: Describe how the binder handles collection properties, including its use of an existing initialized collection or automatic creation of a List<T> for supported collection interfaces. Distinguish the special case that an already initialized IEnumerable<T> cannot be bound because it exposes no Add method and the binder will not replace it.
Why it matters: Collection declarations and initialization affect whether configuration arrays can actually populate your settings. - Dictionary key restrictions: State that dictionary-interface properties can be backed by Dictionary<TKey,TValue> when their keys are strings, enums, or integer types, but cannot be bound with keys such as custom classes or double.
Why it matters: Choosing a supported dictionary key type prevents configuration binding failures for map-like settings.
Key terms: POCO, IOptions<T>, binder, reflection, public parameterless constructor, configuration binder, getter, setter, set-only property, indexer
10.3.4 Binding strongly typed settings without the IOptions interface
This section shows how to bind and inject a strongly typed settings object directly, without requiring consumers to depend on IOptions<T>, and explains the trade-offs.
- Direct settings injection: Describe how to bind a configuration section to a strongly typed settings object, register that object with the DI container, and inject the settings type directly into a handler or service instead of injecting IOptions<T>.
Why it matters: Direct injection can make consumers and reusable libraries simpler by avoiding IOptions<T> in their public APIs. - Direct registration alternatives: Distinguish the two direct-injection registration approaches: manually bind and register the settings object, or register IOptions<T> and use a lambda to additionally register the concrete settings type as a singleton.
Why it matters: Both approaches remove IOptions<T> from consumers while allowing an application to choose how it performs registration. - Direct binding trade-offs: Explain why direct settings injection can simplify consumers, especially reusable libraries, and state that it loses strongly typed reload support and some advanced IOptions capabilities unless additional work is done.
Why it matters: Choosing the simpler registration style requires deciding whether reloadable settings or advanced options features are needed.
Key terms: configuration binder, IConfiguration, configuration section, MapSettings, dependency injection, IOptions<T>, singleton, lambda, DI container, IOptions<T>.Value
10.4 Configuring an application for multiple environments
This section introduces hosting environments as a way to identify where an ASP.NET Core app runs and use appropriate configuration values for that environment.
- Purpose of hosting environments: Explain why an ASP.NET Core application may use different configuration values in development and production, such as different database connection strings and logging levels.
Why it matters: Environments let the same application behave appropriately on a developer machine and on production servers. - Environment configuration tasks: Describe the three environment-related tasks covered in this section: identifying the current hosting environment, loading configuration values for it, and setting the environment on a machine.
Why it matters: These three tasks allow an application to distinguish its execution context and select the right settings.
Key terms: hosting environments, development, production, configuration values, connection string, logging, hosting environment, current environment
10.4.1 Identifying the hosting environment
This section explains how ASP.NET Core identifies the hosting environment and how an app can use that environment information to vary its behavior and configuration.
- Hosting environment identification: Explain how WebApplicationBuilder determines the current hosting environment from environment variables and exposes it through WebApplicationBuilder.Environment as an IHostEnvironment.
Why it matters: The hosting environment lets one application behave differently when it runs locally, in staging, or in production. - Environment names and checks: Describe the conventional Development, Staging, and Production environment names, and explain why IHostEnvironment helper methods should be used to test them instead of directly comparing EnvironmentName strings.
Why it matters: Using the supplied checks avoids case-sensitive environment-name bugs when choosing environment-specific behavior. - Environment context paths: Distinguish ContentRootPath from WebRootPath and state which environment interface exposes each path.
Why it matters: Knowing which root path to use prevents treating application configuration files and browser-accessible static files as though they belong in the same location. - Environment-dependent application behavior: Explain that IHostEnvironment only reports the current environment, while application code uses that information to conditionally enable features such as the development exception page or load different configuration values.
Why it matters: The environment object is useful because it provides the condition for selecting safe, appropriate behavior in each deployment context.
Key terms: WebApplicationBuilder, ASPNETCORE_ENVIRONMENT, DOTNET_ENVIRONMENT, IHostEnvironment, WebApplicationBuilder.Environment, EnvironmentName, Development, Staging, Production, IsDevelopment()
10.4.2 Loading environment-specific configuration files
This section shows how the hosting environment selects configuration sources and application behavior, while keeping environment-specific concerns out of application services.
- Environment-specific JSON configuration: Describe the pattern of loading an optional appsettings.ENVIRONMENT.json file after the global appsettings.json file. Explain that the file chosen depends on EnvironmentName and that matching keys in the environment-specific file override global values.
Why it matters: This lets one application use appropriate settings, such as different logging levels, in development, staging, and production. - Conditional configuration providers: Explain that EnvironmentName is established early during application bootstrapping, so it can determine which configuration providers are added before IConfiguration is built. Describe using IHostEnvironment to add User Secrets in development but a provider such as Azure Key Vault in production.
Why it matters: Conditional providers help keep local development secrets and production secrets in appropriate stores. - Environment-based application behavior: Describe using IHostEnvironment in Program.cs to vary the middleware pipeline, such as using DeveloperExceptionPageMiddleware in local development and ExceptionHandlerMiddleware in staging or production. Explain that application services should generally receive environment-specific strongly typed settings instead of directly depending on IHostEnvironment.
Why it matters: Keeping environment checks at application setup avoids spreading hosting-specific decisions throughout business services.
Key terms: EnvironmentName, appsettings.json, appsettings.Development.json, appsettings.Staging.json, appsettings.Production.json, ConfigurationManager, IHostEnvironment, configuration provider, User Secrets provider, Azure Key Vault
10.4.3 Setting the hosting environment
This section explains how to select an ASP.NET Core hosting environment locally and in production using environment variables, launch profiles, or command-line arguments.
- Hosting environment default: Explain how ASP.NET Core chooses its hosting environment at startup, including the default when ASPNETCORE_ENVIRONMENT is absent.
Why it matters: The active environment controls environment-specific application behavior and configuration. - Launch profile configuration: Describe how launchSettings.json profiles set project-local environment variables and choose how an application runs during local development.
Why it matters: Launch profiles let you test one project under different local settings without changing environment variables for every application on your machine. - Profile selection and deployment: Describe how to select or bypass a launch profile and distinguish local launchSettings.json use from production environment configuration.
Why it matters: Knowing profile precedence and the relevant dotnet run switches prevents local settings from unexpectedly overriding a chosen environment.
Key terms: ASPNETCORE_ENVIRONMENT, hosting environment, Production, Development, launchSettings.json, launch profile, http profile, https profile, IIS Express profile, dotnet run --launch-profile
10.5 Summary
This summary recaps how ASP.NET Core loads, overrides, secures, binds, reloads, and environment-scopes application configuration.
Where this is used later
- The Program class: Building a Web Host (chapter 30) · The ASP.NET Core configuration model.
- Configuring the URLs for your application (chapter 27) · Deployment URL configuration applies the principle of changing application behavior through external configuration.
- Summary (chapter 26) · Using configuration providers and configuration sections.
- Preparing your app for deployment to Linux (chapter 27) · ASP.NET Core configuration can be supplied by environment variables.
- Registering a data context (chapter 12) · Registering a data context commonly obtains a connection string from IConfiguration.
- Summary (chapter 12) · Using configuration to store sensitive values such as connection strings safely.
- (chapter intro) (chapter 31) · Strongly typed settings and the IOptions pattern.
- Using DI with OptionsBuilder and IConfigureOptions (chapter 31) · Strongly typed settings and injecting settings through IOptions<T>
Concepts explained in this chapter
- configuration providerA configuration provider is a component that reads application configuration values from a particular source and contributes them to the configuration system.
- strongly typed optionsAn options object is a strongly typed object whose properties represent a set of related application settings.
- ConfigurationManagerConfigurationManager is the .NET configuration type that builds and exposes application configuration while implementing IConfigurationBuilder and IConfigurationRoot.
- configurationConfiguration is the set of external settings and secrets that control an application's runtime behavior.
- environmentA hosting environment is the runtime context that identifies where an application is running and determines environment-specific configuration and behavior.
- environment variableAn environment variable is an operating-system-provided name-value setting that applications can read at runtime.
- JSON file providerA JSON provider is a configuration provider that reads application settings from JSON-formatted files.
- IConfigurationIConfiguration is the .NET abstraction for reading aggregated application configuration values from key-value configuration sources.
- User SecretsThe User Secrets manager is an ASP.NET Core development tool and configuration provider for storing sensitive settings outside a project directory.
- API keyAn API key is a secret credential used to authenticate an application or request to a remote service.
- IOptionsSnapshot<T>IOptionsSnapshot<T> is a .NET options interface that provides options values capable of reflecting configuration changes across dependency-injection scopes.
- IOptions<T>IOptions<T> is a .NET options abstraction that provides access to a single strongly typed configuration object created on first use.
- AddJsonFile()AddJsonFile() is a .NET configuration extension method that adds a JSON file as a configuration source.
- IConfigurationRootIConfigurationRoot is the .NET configuration interface representing the assembled configuration values and their providers.
- AddEnvironmentVariablesAddEnvironmentVariables is a .NET configuration extension method that adds operating-system environment variables as configuration settings.
- AddUserSecretsAddUserSecrets is a .NET configuration extension method that loads User Secrets for an application.
- sensitive informationSensitive data is information whose disclosure or misuse could harm a person, system, or organization.
- configuration binderA configuration binder is a component that maps a collection of configuration values to the properties of a strongly typed object.
- ASP.NET Core environmentASPNETCORE_ENVIRONMENT is an environment variable that identifies the current ASP.NET Core hosting environment.
- EnvironmentNameEnvironmentName is the hosting-environment property that identifies the current application environment, such as Development, Staging, or Production.
- IHostEnvironmentIHostEnvironment is the .NET abstraction that exposes information about an application's current hosting environment and content root.
- launchSettings.jsonlaunchSettings.json is an ASP.NET Core development configuration file that defines how an application is launched and debugged by development tools.
- ExceptionHandlerMiddlewareError-handling middleware is middleware that intercepts application errors and modifies the HTTP response before it is returned to the client.
- appsettings.Development.jsonappsettings.Development.json is an ASP.NET Core environment-specific application configuration file containing settings for the Development environment.
- MapA dictionary is a key-value data structure that associates each key with a value.
- plain old CLR objectA plain old CLR object is an ordinary .NET object that does not depend on a specialized framework base type or programming model.
- options patternThe IOptions pattern is a .NET configuration pattern that represents application settings as strongly typed options objects obtained through dependency injection.
- appsettings.jsonappsettings.json is a conventional ASP.NET Core configuration file containing application settings in JSON format.
- logging levelThe Information log level records normal application flow and contextual events that help explain subsequent behavior.
These guides are generated from the text of Manning books by Manning's knowledge graph and link to the sections they draw on. The full books are available on liveBook and at manning.com.
