如何在启动中的ConfigureServices方法中获得开发/登台/生产托管环境?

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

ConfigureServices方法只接受一个IServiceCollection参数。


当前回答

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

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

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

其他回答

由于还没有完整的复制和粘贴解决方案,基于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
   }
   ...
}

来自文档

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
}

在Dotnet Core 2.0中,启动构造函数只需要一个iconfigure -parameter。

    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();
}

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

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

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

在. net Core 2.0 MVC app / Microsoft.AspNetCore.All v2.0.0中,你可以有@vaindil所描述的特定于环境的启动类,但我不喜欢这种方法。

你也可以在StartUp构造函数中注入IHostingEnvironment。不需要将环境变量存储在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());
            }            
        });

        ......
    }
}