Configuration Strategy
Outline
- Focus: Environment-specific settings in Optimizely DXP without brittle manual hacks
- Core model: Layered configuration using JSON files, User Secrets, and environment variables
- Recommended pattern: Let configuration supply values instead of hardcoding environment-specific logic
- Operational goal: Promote the same build from Integration to Production without changing code
Mastering environment-specific configuration is one of the definitive hallmarks of a senior Optimizely PaaS developer. In a Digital Experience Platform (DXP) context, your code is a "global citizen" that travels through multiple gated stages: your Local Development Station, the Integration sandbox, the Pre-production staging mirror, and finally, the live Production delivery engine.
A common architectural failure—often referred to as a "brittle hack"—is the reliance on manual toggles, hardcoded conditional blocks based on machine names, or complex #if DEBUG pre-processor directives. These patterns lead to "deployment anxiety" where a build works perfectly in Integration but fails in Production due to a missing manual step. This module explores how to leverage the native .NET 10 configuration ecosystem to build a "write once, run anywhere" solution that is secure, maintainable, and truly cloud-native.
1. The Architectural Foundation: Order of Precedence
Optimizely CMS 13 fully embraces the modern ASP.NET Core configuration provider model. This model isn't just about reading a file; it is an aggregated hierarchy of key-value pairs that are layered on top of each other. The logic is simple: The last provider loaded wins.
The Professional Loading Chain
-
appsettings.json: This is your "Base Layer." Use it for settings that are structurally identical across all environments, such as default UI culture or content-agnostic business rules. -
appsettings.{Environment}.json: This is your "Delta Layer." When the application initializes, it checks theASPNETCORE_ENVIRONMENTvariable. If it's set toIntegration, it loadsappsettings.Integration.json, overwriting any colliding keys from the base file. - User Secrets (Local Only): This is your "Security Buffer." During local development, sensitive keys (like a private API token for a test ERP) should be stored here. This prevents secrets from ever touching your Git repository.
- Environment Variables (The Ultimate Override): In the DXP (Azure) ecosystem, any setting provided via the PaaS Portal configuration tab is injected as an environment variable. These are loaded last and will overwrite even your production JSON files.
Never, under any circumstances, commit a production API key, password, or client secret to an appsettings.json file. If a file is in source control, it is potentially public.
2. Professional Strategy: Environment-Specific Deltas
Instead of writing code that asks "Am I in production?", you should design your code to ask "What is the value of this setting?" and let the configuration layer provide the answer based on the environment.
Example: API Endpoint Management
Consider a real-world scenario where your CMS must communicate with a Corporate Identity API. You have a developer mock instance and a live production endpoint.
appsettings.Development.json
appsettings.Production.json
By leveraging this structure, the developer simply requests the key via the configuration API, and the runtime automatically resolves the correct URL. This creates a zero-touch deployment experience.
3. Strongly Typed Configurations (The Options Pattern)
Using string-based lookups like _config["Settings:Key"] is a "brittle" pattern because it lacks type safety and IntelliSense. The Options Pattern solves this by binding configuration sections directly to plain C# classes.
Step 1: Define a Validated Configuration Class
Step 2: Service Registration in Startup.cs
Step 3: Type-Safe Access via Dependency Injection
4. DXP Constants and Contextual Identification
While file-based configuration covers most use cases, you occasionally need logic that pivots on environment identity—such as enabling a "Dev-only" dashboard in Integration.
Implementation Best Practice: IWebHostEnvironment
Instead of checking machine names, use the standard .NET IWebHostEnvironment interface. DXP automatically populates the EnvironmentName property.
5. DXP Cloud Runtime Configuration (Injected Variables)
When running in DXP, Optimizely injects platform-managed environment variables. These handles allow your code to connect to the Azure stack without manual configuration.
-
APPINSIGHTS_INSTRUMENTATIONKEY: Routes telemetry to Azure Application Insights. -
EPiServerDB: The system connection string, inherited via the Cloud Integration package. -
episerver:EnvironmentName: Historically used by DXP to coordinate automated jobs like cache-purging.
6. Summary for Certification
Success in CMS 13 PaaS development is defined by a build that can be promoted from Integration to Production without a single code change. To pass this module, ensure you can:
- Isolate secrets using environment variables.
- Organize settings via environment-specific JSON files.
- Implement the Type-Safe Options Pattern for all custom integrations.
Conclusion
A reliable configuration strategy in DXP depends on layered settings, environment-aware overrides, and secure secret handling rather than manual edits or hardcoded checks. When developers rely on the native .NET configuration system and strongly typed options, deployments become safer, cleaner, and far more predictable across Integration, Pre-production, and Production.
