Launch Environments vs. Runtime Environments
In ASP.NET Core applications, it is crucial to distinguish between the environment used to start the application and the environment in which the application runs. The development setup described here targets .NET Core 3.1.
Configuring Launch Profiles
The launch environment determines the web server used to host the application during development. This configuration resides in the launchSettings.json file, specifically within the profiles node. Here, developers can toggle between different server configurations:
- IIS Express: Utilizes the local IIS Express server for debugging.
- Project: Launches the application using the built-in Kestrel web server.
Defining Runtime Environments
ASP.NET Core provides three predefined runtime environments out of the box:
- Development: Typically used for local coding and debugging.
- Staging: A pre-production environment for final testing.
- Production: The live environment serving end-users.
The active runtime environment can be detected within the Startup class using the IWebHostEnvironment service. This service provides extension methods to check the current context:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
// Development specific logic
}
if (env.IsProduction())
{
// Production specific logic
}
if (env.IsStaging())
{
// Staging specific logic
}
}
Custom Environment Configuration
The default environment is Development if not specified otherwise. To define a custom environment, modify the ASPNETCORE_ENVIRONMENT variable within the launchSettings.json profile:
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "CustomEnv"
}
When working with custom environment names, the standard IsEnvironment method can be used for verification:
if (env.IsEnvironment("CustomEnv"))
{
// Logic for CustomEnv
}
Strategies for Environment-Specific Logic
Convention-Based Startup Methods
ASP.NET Core supports method naming conventions to separate configuration logic based on the environment. By suffixing the environment name to Configure or ConfigureServices, the framework automatically invokes the appropriate method. If a specific method is not found, it defaults to the base method.
The default configuration methods appear as follows:
public void ConfigureServices(IServiceCollection services)
{
// Default service registration
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// Default application configuration
}
For a Development environment, you can isolate the logic like this:
public void ConfigureServicesDevelopment(IServiceCollection services)
{
// Services specific to Development
}
public void ConfigureDevelopment(IApplicationBuilder app, IWebHostEnvironment env)
{
// Middleware specific to Development
}
Environment-Specific Startup Classes
For more substantial differences between environments, entirely separate Startup classes can be utilized. The naming convention follows the pattern Startup{EnvironmentName}. The host builder must be configured to select the appropriate startup class, often using the assembly name approach.
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup(typeof(Program).Assembly.FullName);
});
With this configuration, the framework will search for a class named StartupDevelopment when the environment is Development. If the specific class does not exist, it falls back to the standard Startup class.
public class Startup
{
// Default configuration
}
public class StartupDevelopment
{
// Development-only configuration
}