如何通过“ ConfigureServices
启动” 中的方法获得“开发/登台/生产”托管环境?
public void ConfigureServices(IServiceCollection services)
{
// Which environment are we running under?
}
该ConfigureServices
方法仅采用一个IServiceCollection
参数。
如何通过“ ConfigureServices
启动” 中的方法获得“开发/登台/生产”托管环境?
public void ConfigureServices(IServiceCollection services)
{
// Which environment are we running under?
}
该ConfigureServices
方法仅采用一个IServiceCollection
参数。
Answers:
您可以在ConfigureServices中轻松访问它,只需在启动方法期间将其持久保存到属性中,该方法将首先被调用并传递给它,然后您可以从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...
}
CurrentEnvironment.IsEnvironment("environmentname")
。
CurrentEnvironment.IsDevelopment()
/CurrentEnvironment.IsProduction()
设置一个名为环境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托管层提供,可以通过“依赖项注入”注入到您的启动逻辑中。Visual Studio中的ASP.NET Core网站模板使用此方法来加载特定于环境的配置文件(如果存在)并自定义应用程序的错误处理设置。在这两种情况下,此行为都是通过调用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()
在同一环境中。
在.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's Production, enable HTTPS
if (_currentEnvironment.IsProduction()) // <------
{
config.Filters.Add(new RequireHttpsAttribute());
}
});
......
}
}
无需任何额外的属性或方法参数即可完成此操作,如下所示:
public void ConfigureServices(IServiceCollection services)
{
IServiceProvider serviceProvider = services.BuildServiceProvider();
IHostingEnvironment env = serviceProvider.GetService<IHostingEnvironment>();
if (env.IsProduction()) DoSomethingDifferentHere();
}
根据文档
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
}
我想在我的一项服务中获得环境。真的很容易做到!我只是将其注入到构造函数中,如下所示:
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.
}
上面的代码适用于.NET Core2。对于版本3,您将需要使用IWebHostEnvironment
。
宿主环境来自ASPNET_ENV环境变量,该变量在启动过程中可以使用IHostingEnvironment.IsEnvironment扩展方法或IsDevelopment或IsProduction的相应便捷方法之一提供。在Startup()或ConfigureServices调用中保存所需的内容:
var foo = Environment.GetEnvironmentVariable("ASPNET_ENV");
IHostingEnvironment
在中不可用ConfigureServices
。
以防万一有人也在寻找这个。在.net core 3+中,大多数功能已过时。更新方式为:
public void Configure(
IApplicationBuilder app,
IWebHostEnvironment env,
ILogger<Startup> logger)
{
if (env.EnvironmentName == Environments.Development)
{
// logger.LogInformation("In Development environment");
}
}
在Dotnet Core 2.0中,启动构造函数仅需要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();
}
IHostingEnvironment
只注入ConfigureServices?监督?还是我们需要注意的原因?