Reputation: 38417
How do I get the Development/Staging/production Hosting Environment in the ConfigureServices
method in Startup?
public void ConfigureServices(IServiceCollection services)
{
// Which environment are we running under?
}
The ConfigureServices
method only takes a single IServiceCollection
parameter.
Upvotes: 373
Views: 284398
Reputation: 39
In .NET6.0 Use the following:
var env = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
This will say "Development" if it is in development mode.
The variable "DEV_ENVIRONMENT" also will be set to 1 in dev environment.
Upvotes: 0
Reputation: 12410
from the docs
Configure and ConfigureServices support environment specific versions of the form Configure{EnvironmentName} and Configure{EnvironmentName}Services:
You can do something like this...
public void ConfigureProductionServices(IServiceCollection services)
{
ConfigureCommonServices(services);
//Services only for production
services.Configure();
}
public void ConfigureDevelopmentServices(IServiceCollection services)
{
ConfigureCommonServices(services);
//Services only for development
services.Configure();
}
public void ConfigureStagingServices(IServiceCollection services)
{
ConfigureCommonServices(services);
//Services only for staging
services.Configure();
}
private void ConfigureCommonServices(IServiceCollection services)
{
//Services common to each environment
}
Upvotes: 26
Reputation: 936
In NET6, Startup and Program have merged into a single file, there is no ConfigureServices
method in Startup anymore. Now you can simply use
builder.Environment.IsProduction()
builder.Environment.IsStaging()
builder.Environment.IsDevelopment()
right after the first line
var builder = WebApplication.CreateBuilder(args);
Upvotes: 34
Reputation: 36696
You can easily access it in ConfigureServices, just persist it to a property during Startup method which is called first and gets it passed in, then you can access the property from ConfigureServices.
public Startup(IWebHostEnvironment env, IApplicationEnvironment appEnv)
{
...your code here...
CurrentEnvironment = env;
}
private IWebHostEnvironment CurrentEnvironment{ get; set; }
public void ConfigureServices(IServiceCollection services)
{
string envName = CurrentEnvironment.EnvironmentName;
... your code here...
}
Upvotes: 425
Reputation: 1611
Another way is to read the environment name directly from the configuration with Configuration["ASPNETCORE_ENVIRONMENT"]
. This works everywhere where you can access configuration.
public IConfiguration Configuration { get; }
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public void ConfigureServices(IServiceCollection services)
{
Console.WriteLine(Configuration["ASPNETCORE_ENVIRONMENT"]);
}
Prerequisite is that the host was created with Host.CreateDefaultBuilder() in Programm.cs which is the default for ASP.NET Core 3.0 (and 5.0) web apps. If another builder is used the envars can be added with AddEnvironmentVariables() in Programm.cs.
Upvotes: 5
Reputation: 45
For a blazor server app I did this: Startup.cs
directly under the namespace declaration add
namespace myProjectName.Server
public static class myGlobals
{
public static bool isDevelopment = true;
}
Startup.cs
find the Configure
method and the existing check for env.IsDevelopment
and set the static isDeveloment
declared above to true
or false
.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
myGlobals.isDevelopment = true;
}
else false
In ApplicationUser
when you are initializing the database connection or anywhere else
if (myGlobals.isDevelopment)
{
Upvotes: -2
Reputation: 25956
Starting from ASP.NET Core 3.0, it is much simpler to access the environment variable from both ConfigureServices
and Configure
.
Simply inject IWebHostEnvironment
into the Startup constructor itself. Like so...
public class Startup
{
public Startup(IConfiguration configuration, IWebHostEnvironment env)
{
Configuration = configuration;
_env = env;
}
public IConfiguration Configuration { get; }
private readonly IWebHostEnvironment _env;
public void ConfigureServices(IServiceCollection services)
{
if (_env.IsDevelopment())
{
//development
}
}
public void Configure(IApplicationBuilder app)
{
if (_env.IsDevelopment())
{
//development
}
}
}
Upvotes: 39
Reputation: 967
Since there is no full copy & paste solution yet, based on Joe Audette's answer:
public IWebHostEnvironment Environment { get; }
public Startup(IWebHostEnvironment environment, IConfiguration configuration)
{
Environment = environment;
...
}
public void ConfigureServices(IServiceCollection services)
{
if (Environment.IsDevelopment())
{
// Do something
}else{
// Do something
}
...
}
Upvotes: 8
Reputation: 1357
Just in case someone is looking to this too. In .net core 3+ most of this is obsolete. The update way is:
public void Configure(
IApplicationBuilder app,
IWebHostEnvironment env,
ILogger<Startup> logger)
{
if (env.EnvironmentName == Environments.Development)
{
// logger.LogInformation("In Development environment");
}
}
Upvotes: 4
Reputation: 25029
I wanted to get the environment in one of my services. It is really easy to do! I just inject it to the constructor like this:
private readonly IHostingEnvironment _hostingEnvironment;
public MyEmailService(IHostingEnvironment hostingEnvironment)
{
_hostingEnvironment = hostingEnvironment;
}
Now later on in the code I can do this:
if (_hostingEnvironment.IsProduction()) {
// really send the email.
}
else {
// send the email to the test queue.
}
Code above is for .NET Core 2. For version 3 you will want to use IWebHostEnvironment
.
Upvotes: 25
Reputation: 2421
If you need to test this somewhere in your codebase that doesn't have easy access to the IHostingEnvironment, another easy way to do it is like this:
bool isDevelopment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "Development";
Upvotes: 119
Reputation: 791
This can be accomplished without any extra properties or method parameters, like so:
public void ConfigureServices(IServiceCollection services)
{
IServiceProvider serviceProvider = services.BuildServiceProvider();
IHostingEnvironment env = serviceProvider.GetService<IHostingEnvironment>();
if (env.IsProduction()) DoSomethingDifferentHere();
}
Upvotes: 42
Reputation: 21476
In .NET Core 2.0
MVC app / Microsoft.AspNetCore.All
v2.0.0, you can have environmental specific startup class as described by @vaindil but I don't like that approach.
You can also inject IHostingEnvironment
into StartUp
constructor. You don't need to store the environment variable in Program
class.
public class Startup
{
private readonly IHostingEnvironment _currentEnvironment;
public IConfiguration Configuration { get; private set; }
public Startup(IConfiguration configuration, IHostingEnvironment env)
{
_currentEnvironment = env;
Configuration = configuration;
}
public void ConfigureServices(IServiceCollection services)
{
......
services.AddMvc(config =>
{
// Requiring authenticated users on the site globally
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
config.Filters.Add(new AuthorizeFilter(policy));
// Validate anti-forgery token globally
config.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
// If it's Production, enable HTTPS
if (_currentEnvironment.IsProduction()) // <------
{
config.Filters.Add(new RequireHttpsAttribute());
}
});
......
}
}
Upvotes: 36
Reputation: 518
In Dotnet Core 2.0 the Startup-constructor only expects a IConfiguration-parameter.
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
How to read hosting environment there? I store it in Program-class during ConfigureAppConfiguration (use full BuildWebHost instead of WebHost.CreateDefaultBuilder):
public class Program
{
public static IHostingEnvironment HostingEnvironment { get; set; }
public static void Main(string[] args)
{
// Build web host
var host = BuildWebHost(args);
host.Run();
}
public static IWebHost BuildWebHost(string[] args)
{
return new WebHostBuilder()
.UseConfiguration(new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("hosting.json", optional: true)
.Build()
)
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.ConfigureAppConfiguration((hostingContext, config) =>
{
var env = hostingContext.HostingEnvironment;
// Assigning the environment for use in ConfigureServices
HostingEnvironment = env; // <---
config
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
if (env.IsDevelopment())
{
var appAssembly = Assembly.Load(new AssemblyName(env.ApplicationName));
if (appAssembly != null)
{
config.AddUserSecrets(appAssembly, optional: true);
}
}
config.AddEnvironmentVariables();
if (args != null)
{
config.AddCommandLine(args);
}
})
.ConfigureLogging((hostingContext, builder) =>
{
builder.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
builder.AddConsole();
builder.AddDebug();
})
.UseIISIntegration()
.UseDefaultServiceProvider((context, options) =>
{
options.ValidateScopes = context.HostingEnvironment.IsDevelopment();
})
.UseStartup<Startup>()
.Build();
}
Ant then reads it in ConfigureServices like this:
public IServiceProvider ConfigureServices(IServiceCollection services)
{
var isDevelopment = Program.HostingEnvironment.IsDevelopment();
}
Upvotes: 3
Reputation: 7846
Set an environment variable called ASPNETCORE_ENVIRONMENT
with the name of the environment (e.g. Production
). Then do one of two things:
IHostingEnvironment
into Startup.cs
, then use that (env
here) to check: env.IsEnvironment("Production")
. Do not check using env.EnvironmentName == "Production"
!Startup
classes or individual Configure
/ConfigureServices
functions. If a class or the functions match these formats, they will be used instead of the standard options on that environment.
Startup{EnvironmentName}()
(entire class) || example: StartupProduction()
Configure{EnvironmentName}()
|| example: ConfigureProduction()
Configure{EnvironmentName}Services()
|| example: ConfigureProductionServices()
The .NET Core docs describe how to accomplish this. Use an environment variable called ASPNETCORE_ENVIRONMENT
that's set to the environment you want, then you have two choices.
The
IHostingEnvironment
service provides the core abstraction for working with environments. This service is provided by the ASP.NET hosting layer, and can be injected into your startup logic via Dependency Injection. The ASP.NET Core web site template in Visual Studio uses this approach to load environment-specific configuration files (if present) and to customize the app’s error handling settings. In both cases, this behavior is achieved by referring to the currently specified environment by callingEnvironmentName
orIsEnvironment
on the instance ofIHostingEnvironment
passed into the appropriate method.
NOTE: Checking the actual value of env.EnvironmentName
is not recommended!
If you need to check whether the application is running in a particular environment, use
env.IsEnvironment("environmentname")
since it will correctly ignore case (instead of checking ifenv.EnvironmentName == "Development"
for example).
When an ASP.NET Core application starts, the
Startup
class is used to bootstrap the application, load its configuration settings, etc. (learn more about ASP.NET startup). However, if a class exists namedStartup{EnvironmentName}
(for exampleStartupDevelopment
), and theASPNETCORE_ENVIRONMENT
environment variable matches that name, then thatStartup
class is used instead. Thus, you could configureStartup
for development, but have a separateStartupProduction
that would be used when the app is run in production. Or vice versa.In addition to using an entirely separate
Startup
class based on the current environment, you can also make adjustments to how the application is configured within aStartup
class. TheConfigure()
andConfigureServices()
methods support environment-specific versions similar to theStartup
class itself, of the formConfigure{EnvironmentName}()
andConfigure{EnvironmentName}Services()
. If you define a methodConfigureDevelopment()
it will be called instead ofConfigure()
when the environment is set to development. Likewise,ConfigureDevelopmentServices()
would be called instead ofConfigureServices()
in the same environment.
Upvotes: 83
Reputation: 893
The hosting environment comes from the ASPNET_ENV environment variable, which is available during Startup using the IHostingEnvironment.IsEnvironment extension method, or one of the corresponding convenience methods of IsDevelopment or IsProduction. Either save what you need in Startup(), or in ConfigureServices call:
var foo = Environment.GetEnvironmentVariable("ASPNET_ENV");
Upvotes: 6