如何在ConfigureServices中获取开发/暂存/生产主机环境

时间:2015-09-13 10:56:10

标签: c# asp.net-core asp.net-core-mvc

如何在启动时的ConfigureServices方法中获取开发/暂存/生产主机环境?

public void ConfigureServices(IServiceCollection services)
{
    // Which environment are we running under?
}

ConfigureServices方法只需要一个IServiceCollection参数。

12 个答案:

答案 0 :(得分:132)

您可以在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...
}

答案 1 :(得分:39)

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 docs describe how to accomplish this。使用名为ASPNETCORE_ENVIRONMENT的环境变量设置为您想要的环境,然后您有两个选择。

检查环境名称

From the docs

  

IHostingEnvironment服务提供了处理环境的核心抽象。此服务由ASP.NET托管层提供,可以通过依赖注入注入到启动逻辑中。 Visual Studio中的ASP.NET Core网站模板使用此方法加载特定于环境的配置文件(如果存在)并自定义应用程序的错误处理设置。在这两种情况下,通过在传递给适当方法的EnvironmentName实例上调用IsEnvironmentIHostingEnvironment来引用当前指定的环境来实现此行为。

注意:检查env.EnvironmentName的实际值是不是推荐!

  

如果您需要检查应用程序是否在特定环境中运行,请使用env.IsEnvironment("environmentname"),因为它会正确忽略大小写(而不是检查是否env.EnvironmentName == "Development")。

使用单独的类

From the docs

  

当ASP.NET Core应用程序启动时,Startup类用于引导应用程序,加载其配置设置等(learn more about ASP.NET startup)。但是,如果存在名为Startup{EnvironmentName}的类(例如StartupDevelopment),并且ASPNETCORE_ENVIRONMENT环境变量与该名称匹配,则使用该Startup类。因此,您可以配置Startup进行开发,但是在应用程序在生产环境中运行时会使用单独的StartupProduction。反之亦然。

     

除了根据当前环境使用完全独立的Startup类之外,您还可以调整应用程序在Startup类中的配置方式。 Configure()ConfigureServices()方法支持类似于Startup类本身的特定于环境的版本,其格式为Configure{EnvironmentName}()Configure{EnvironmentName}Services()。如果您定义方法ConfigureDevelopment(),则在环境设置为开发时将调用它而不是Configure()。同样,在同一环境中,ConfigureDevelopmentServices()将被调用而不是ConfigureServices()

答案 2 :(得分:15)

RuntimeError: Model class customer.tests.tests_lib_restless_ext.SampleModel doesn't declare an explicit app_label and isn't in an application in INSTALLED_APPS. MVC app / .NET Core 2.0 v2.0.0中,您可以使用@vaindil所描述的环境特定的启动类,但我不喜欢这种方法。

您还可以将Microsoft.AspNetCore.All注入IHostingEnvironment构造函数。您不需要将环境变量存储在StartUp类中。

Program

答案 3 :(得分:8)

这可以在没有任何额外属性或方法参数的情况下完成,如下所示:

public void ConfigureServices(IServiceCollection services)
{
    IServiceProvider serviceProvider = services.BuildServiceProvider();
    IHostingEnvironment env = serviceProvider.GetService<IHostingEnvironment>();

    if (env.IsProduction()) DoSomethingDifferentHere();
}

答案 4 :(得分:3)

符合docs

  

Configure和ConfigureServices支持特定于环境的版本   配置{EnvironmentName}和配置{EnvironmentName}服务:

的形式

你可以这样做......

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
}

答案 5 :(得分:3)

我想在其中一项服务中获得环境。这真的很容易做到!我只是将它注入到这样的构造函数中:

    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.
}

答案 6 :(得分:3)

以防万一有人也在寻找这个。在.net core 3+中,大多数功能已过时。更新方式为:

public void Configure(
    IApplicationBuilder app,
    IWebHostEnvironment env,
    ILogger<Startup> logger)
{
    if (env.EnvironmentName == Environments.Development)
    {
        // logger.LogInformation("In Development environment");
    }
}

答案 7 :(得分:1)

在Dotnet Core 2.0中,Startup构造函数只需要一个IConfiguration参数。

    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

如何阅读托管环境? 我在ConfigureAppConfiguration期间将它存储在Program-class中 (使用完整的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 :(得分:1)

如果您需要在代码库中无法轻松访问IHostingEnvironment的位置进行测试,则另一种简单的方法如下:

bool isDevelopment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "Development";

答案 9 :(得分:0)

由于尚无完整的复制和粘贴解决方案,因此根据Joe Audette的回答:

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
   }
   ...
}

答案 10 :(得分:0)

从ASP.NET Core 3.0开始,从ConfigureServicesConfigure访问环境变量要简单得多。

只需将IWebHostEnvironment注入Startup构造函数本身。像这样...

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
        }
    }
}

参考:https://docs.microsoft.com/en-us/aspnet/core/fundamentals/environments?view=aspnetcore-3.0#inject-iwebhostenvironment-into-the-startup-class

答案 11 :(得分:0)

对于 blazor 服务器应用程序,我这样做了:Startup.cs 直接在命名空间声明下添加

namespace myProjectName.Server

public static class myGlobals

{
    public static bool isDevelopment = true;
}

Startup.cs 找到 Configure 方法和现有的 env.IsDevelopment 检查并将上面声明的 static isDeveloment 设置为 truefalse。< /p>

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
           myGlobals.isDevelopment = true;
        }
        else false

ApplicationUser 中初始化数据库连接或其他任何地方

        if (myGlobals.isDevelopment)
        {