Как получить среду хостинга разработки/размещения/производства в ConfigureServices
Как мне получить среду разработки хостинга разработки/постановки/производства в методе ConfigureServices
в режиме запуска?
public void ConfigureServices(IServiceCollection services)
{
// Which environment are we running under?
}
Метод ConfigureServices
принимает только один параметр IServiceCollection
.
Ответы
Ответ 1
вы можете легко получить доступ к нему в ConfigureServices, просто сохраните его в свойстве во время метода Startup, который вызывается первым и получает его, а затем вы можете получить доступ к свойству из ConfigureServices
public Startup(IHostingEnvironment env, IApplicationEnvironment appEnv)
{
...your code here...
CurrentEnvironment = env;
}
private IHostingEnvironment CurrentEnvironment{ get; set; }
public void ConfigureServices(IServiceCollection services)
{
string envName = CurrentEnvironment.EnvironmentName;
... your code here...
}
Ответ 2
TL; DR
Задайте переменную среды с именем ASPNETCORE_ENVIRONMENT
с именем среды (например, Production
). Затем выполните одно из двух действий:
- Вставьте
IHostingEnvironment
в Startup.cs
, затем используйте (env
здесь), чтобы проверить: env.IsEnvironment("Production")
. Не, используя env.EnvironmentName == "Production"
!
- Используйте либо отдельные классы
Startup
, либо отдельные функции Configure
/ConfigureServices
. Если класс или функции соответствуют этим форматам, они будут использоваться вместо стандартных параметров в этой среде.
-
Startup{EnvironmentName}()
(весь класс) || Пример: StartupProduction()
-
Configure{EnvironmentName}()
|| Пример: ConfigureProduction()
-
Configure{EnvironmentName}Services()
|| Пример: ConfigureProductionServices()
Полное объяснение
В документах .NET Core описывается, как это сделать. Используйте переменную среды с именем ASPNETCORE_ENVIRONMENT
, которая настроена на нужную вам среду, тогда у вас есть два варианта.
Проверить имя среды
Из документов:
Служба IHostingEnvironment
предоставляет основную абстракцию для работы с средами. Эта услуга предоставляется уровнем хостинга ASP.NET и может быть введена в вашу логику запуска через Injection Dependency. Шаблон веб-сайта ASP.NET Core в Visual Studio использует этот подход для загрузки файлов конфигурации среды (если они есть) и для настройки параметров обработки ошибок приложений. В обоих случаях это поведение достигается путем обращения к текущей среде, вызвав EnvironmentName
или IsEnvironment
в экземпляре IHostingEnvironment
, переданном соответствующему методу.
ПРИМЕЧАНИЕ. Рекомендуется проверить фактическое значение env.EnvironmentName
не!
Если вам нужно проверить, работает ли приложение в конкретной среде, используйте env.IsEnvironment("environmentname")
, поскольку он будет правильно игнорировать регистр (вместо проверки, если env.EnvironmentName == "Development"
например).
Использовать отдельные классы
Из документов:
Когда запускается приложение ASP.NET Core, класс Startup
используется для загрузки приложения, загрузки его параметров конфигурации и т.д. (узнать больше о Запуск ASP.NET). Однако, если класс существует с именем Startup{EnvironmentName}
(например, StartupDevelopment
), а переменная среды ASPNETCORE_ENVIRONMENT
соответствует этому имени, тогда вместо этого используется класс Startup
. Таким образом, вы можете настроить Startup
для разработки, но иметь отдельный StartupProduction
, который будет использоваться, когда приложение будет запущено в процессе производства. Или наоборот.
В дополнение к использованию полностью отдельного класса Startup
на основе текущей среды вы также можете внести изменения в настройку приложения в классе Startup
. Методы Configure()
и ConfigureServices()
поддерживают версии, специфичные для среды, похожие на сам класс Startup
, вида Configure{EnvironmentName}()
и Configure{EnvironmentName}Services()
. Если вы определяете метод ConfigureDevelopment()
, он будет вызываться вместо Configure()
, когда среда настроена на разработку. Аналогично, ConfigureDevelopmentServices()
будет вызываться вместо ConfigureServices()
в той же среде.
Ответ 3
В .NET Core 2.0
MVC app/ Microsoft.AspNetCore.All
v2.0.0 вы можете иметь класс запуска для среды, описанный @vaindil, но мне не нравится этот подход.
Вы также можете вставить IHostingEnvironment
в конструктор StartUp
. Вам не нужно сохранять переменную окружения в классе Program
.
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 Production, enable HTTPS
if (_currentEnvironment.IsProduction()) // <------
{
config.Filters.Add(new RequireHttpsAttribute());
}
});
......
}
}
Ответ 4
Это может быть выполнено без каких-либо дополнительных свойств или параметров метода, например так:
public void ConfigureServices(IServiceCollection services)
{
IServiceProvider serviceProvider = services.BuildServiceProvider();
IHostingEnvironment env = serviceProvider.GetService<IHostingEnvironment>();
if (env.IsProduction()) DoSomethingDifferentHere();
}
Ответ 5
Хостинг-окружение происходит из переменной среды ASPNET_ENV, которая доступна во время запуска с использованием метода расширения IHostingEnvironment.IsEnvironment или одного из соответствующих методов удобства IsDevelopment или IsProduction. Или сохраните то, что вам нужно в Startup() или вызове ConfigureServices:
var foo = Environment.GetEnvironmentVariable("ASPNET_ENV");
Ответ 6
согласно документам
Configure и ConfigureServices поддерживают специфичные для среды версии в форме Configure {EnvironmentName} и Configure {EnvironmentName} Services:
Вы можете сделать что-то вроде этого...
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
}
Ответ 7
В Dotnet Core 2.0 конструктор Startup только ожидает параметр IConfiguration.
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
Как читать хостинговую среду?
Я храню его в программном классе во время ConfigureAppConfiguration
(используйте полный BuildWebHost вместо 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 затем читает его в ConfigureServices следующим образом:
public IServiceProvider ConfigureServices(IServiceCollection services)
{
var isDevelopment = Program.HostingEnvironment.IsDevelopment();
}
Ответ 8
Я хотел получить окружающую среду в одном из моих сервисов. Это действительно легко сделать!
private readonly IHostingEnvironment _hostingEnvironment;
public MyEmailService(IHostingEnvironment hostingEnvironment)
{
_hostingEnvironment = hostingEnvironment;
}
Теперь позже в коде я могу сделать это:
if (_hostingEnvironment.IsProduction()) {
// really send the email.
}
else {
// send the email to the test queue.
}