Подтвердить что ты не робот

Как получить среду хостинга разработки/размещения/производства в ConfigureServices

Как мне получить среду разработки хостинга разработки/постановки/производства в методе ConfigureServices в режиме запуска?

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

Метод ConfigureServices принимает только один параметр IServiceCollection.

4b9b3361

Ответ 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.
}