.NET Core has the concept of the environment. An environment is basically a runtime setting in the form of an environment variable called ASPNETCORE_ENVIRONMENT. This variable can take one of the following values (note that these are case sensitive):
Development: A development environment, which probably does not need much explaining
Staging: A preproduction environment used for testing
Production: An environment (or as similar as possible) in which the application will live once it is released
To be specific, you can pass any value, but these have particular significance to .NET Core. There are several ways by which you can access the current environment, but you're most likely to use one of the following methods, extension methods and properties of the IWebHostEnvironment interface (add a using reference to the Microsoft.Extensions.Hosting namespace):
IsDevelopment()
IsProduction()
IsStaging()
IsEnvironment("SomeEnvironment")
EnvironmentName
The IsDevelopment, IsProduction, and IsStaging extension methods are just convenience methods using the IsEnvironment method. Based on the actual environment, you can make decisions about the code, such as picking a different connection string, web service URL, and so on. It is important to point out that this has nothing to do with debug or release compiler configurations.
You normally get an instance of IWebHostEnvironment from the arguments to the Configure method of the Startup class:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { ... }
But you also get it from the DI container, which is available from the HttpContext class, among other places, as the RequestServices property:
var env = HttpContext.RequestServices.GetService<IWebHostEnvironment>();
Or you can just inject IWebHostEnvironment into your controller as the following:
public IActionResult Index([FromServices] IWebHostEnvironment env) { ... }
This allows you to check your current environment any time, so that you have conditional logic.
The IWebHostEnvironment replaces the old IHostingEnvironment interface available in pre-3 .NET Core, now deprecated.
A final note: service configuration plays well with environments. Instead of a single ConfigureServices method, we can have multiple methods, named ConfigureDevelopmentServices, ConfigureStagingServices, and ConfigureProductionServices. To be clear, any environment name can be added after the Configure prefix and before Services. The environment-specific method (for example, ConfigureDevelopmentServices) will be called instead of the generic one (ConfigureServices):
public void ConfigureDevelopmentServices(IServiceCollection services) { //WILL be called for environment Development }
public void ConfigureServices(IServiceCollection services) { //will NOT be called for environment Development }
And, if we want to take it a bit further, we can even do the same for the Startup class: we can create one class per environment, with it as the suffix:
public class StartupDevelopment { public StartupDevelopment(IConfiguration configuration) { ... }
public void ConfigureServices(IServiceCollection services) { ... }
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { ... } }
Or, if we want to dynamically specify a class that resides in a different assembly, we'll have to slightly change the code in the Program class, so as to bootstrap from an assembly:
A nice feature that can help us better organize our code! Let's now have a look at the standard project templates that we can use to start creating our projects.