ConfigureServices'te Geliştirme / Hazırlama / Üretim Barındırma Ortamı nasıl edinilir


171

Geliştirme ConfigureServicesyönteminde Geliştirme / Hazırlama / Üretim Barındırma Ortamı'nı nasıl edinebilirim ?

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

ConfigureServicesYöntem, tek bir alan IServiceCollectionparametre.


4
neden IHostingEnvironmentsadece ConfigureServices içine enjekte edilemiyor ? gözetim? ya da farkında olmamız gereken bir neden?
Simon_Weaver

Yanıtlar:


225

ConfigureServices içinde kolayca erişebilirsiniz, sadece ilk çağrılan ve geçirilen Başlangıç ​​yöntemi sırasında bir özelliğe devam edin, sonra özelliğe ConfigureServices'ten erişebilirsiniz.

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

13
Dokümanlara göre , bu yöntem kullanılmamalıdır. Bunun yerine kullanıyor olmalısınız CurrentEnvironment.IsEnvironment("environmentname").
vaindil

28
veya CurrentEnvironment.IsDevelopment()/CurrentEnvironment.IsProduction()
Simon_Weaver

3
@vaindil - başvurduğunuz dokümanlar bu yöntemin kullanılmaması gerektiğini söylemez.
Örneğiniz

3
@ Coruscate5 Tamam, açıkça bu yöntemi KULLANMAYIN demiyor, ancak diğer yöntemi INSTEAD kullandığını söylüyor. Bu neredeyse aynı şey.
vaindil

8
kullanımdan kaldırıldı IHostingEnvironment env bunun yerine IWebHostEnvironment env kullan
Mark Schultheiss

56

TL; DR

Adlı bir ortam değişkeni ayarlama ASPNETCORE_ENVIRONMENT (örn. Production). Sonra iki şeyden birini yapın:

  • Inject IHostingEnvironmentiçine Startup.cs, daha sonra (yani kullanmak envkontrol etmek için burayı): env.IsEnvironment("Production").Kullanarak kontrol etmeyinenv.EnvironmentName == "Production" !
  • Ayrı Startupsınıflar veya bireysel sınıflar kullanınConfigure / ConfigureServicesişlevler kullanın. Bir sınıf veya işlevler bu biçimlerle eşleşiyorsa, söz konusu ortamdaki standart seçenekler yerine kullanılır.
    • Startup{EnvironmentName}() (tüm sınıf) || misal:StartupProduction()
    • Configure{EnvironmentName}()|| misal:ConfigureProduction()
    • Configure{EnvironmentName}Services()|| misal:ConfigureProductionServices()

Tam açıklama

.NET Core belgeleri bunun nasıl yapılacağını açıklar . Adlı bir ortam değişkeni kullanınASPNETCORE_ENVIRONMENT ayarlanmış , sonra iki seçeneğiniz vardır.

Ortam adını kontrol edin

Dokümanlardan :

IHostingEnvironmentHizmet ortamları ile çalışmak için çekirdek Özet sağlar. Bu hizmet ASP.NET barındırma katmanı tarafından sağlanır ve Bağımlılık Enjeksiyonu yoluyla başlangıç ​​mantığınıza enjekte edilebilir. Visual Studio'daki ASP.NET Core web sitesi şablonu, bu yaklaşımı ortama özgü yapılandırma dosyalarını (varsa) yüklemek ve uygulamanın hata işleme ayarlarını özelleştirmek için kullanır. Her iki durumda da, bu davranış şu anda belirtilen ortama çağrılarak EnvironmentNameveya uygun yönteme aktarılan IsEnvironmentörnek üzerinden gerçekleştirilir IHostingEnvironment.

NOT: gerçek değerini kontrol etme env.EnvironmentNameedilir değil tavsiye!

Uygulamanın belirli bir ortamda çalışıp çalışmadığını kontrol etmeniz gerekiyorsa, env.IsEnvironment("environmentname")büyük / küçük harfleri görmezden geldiği env.EnvironmentName == "Development"için kullanın ( örneğin , kontrol etmek yerine ).

Ayrı sınıflar kullanın

Dokümanlardan :

Bir ASP.NET Core uygulaması başladığında, Startupsınıf uygulamayı başlatmak, yapılandırma ayarlarını yüklemek vb. İçin kullanılır ( ASP.NET başlatma hakkında daha fazla bilgi edinin ). Ancak, adlandırılmış bir sınıf varsa Startup{EnvironmentName}(örneğin StartupDevelopment) ve ASPNETCORE_ENVIRONMENTortam değişkeni bu adla eşleşiyorsa, Startupbunun yerine bu sınıf kullanılır. Böylece, Startupgeliştirme için yapılandırabilirsiniz , ancak StartupProductionuygulama üretimde çalıştırıldığında kullanılacak ayrı bir var. Ya da tam tersi.

StartupGeçerli ortama dayalı olarak tamamen ayrı bir sınıf kullanmaya ek olarak , uygulamanın bir Startupsınıf içinde nasıl yapılandırıldığına dair ayarlamalar da yapabilirsiniz . Configure()Ve ConfigureServices()yöntemler benzer ortama özgü sürümlerini destek Startupbiçiminin sınıfın kendisi, Configure{EnvironmentName}()ve Configure{EnvironmentName}Services(). Bir yöntem tanımlarsanız , ortamın ne zaman geliştirmeye ayarlandığı ConfigureDevelopment()yerine bu yöntem çağrılır Configure(). Aynı şekilde, aynı ortam ConfigureDevelopmentServices()yerine çağrılır ConfigureServices().


29

In .NET Core 2.0MVC uygulaması / Microsoft.AspNetCore.All@vaindil tarif ettiği v2.0.0, sen çevresel belirli başlangıç sınıfı olabilir ama o yaklaşım gibi yapma.

Ayrıca enjekte IHostingEnvironmentiçine StartUpyapıcısı. Ortam değişkenini Programsınıfta depolamanız gerekmez .

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

        ......
    }
}

1
Ayrıntılar şurada
André Morales

André tarafından gönderilen İngilizce link: docs.microsoft.com/en-us/aspnet/core/fundamentals/…
ahong

1
kullanımdan kaldırıldı IHostingEnvironment env bunun yerine IWebHostEnvironment env kullan
Mark Schultheiss

21

Bu, aşağıdaki gibi ekstra özellikler veya yöntem parametreleri olmadan gerçekleştirilebilir:

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

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

2
en iyi cevap. thanx
Shady Sherif

7
Bu, .NET Core 3.0'da aşağıdaki uyarıyı atar: Uygulama kodundan 'BuildServiceProvider' çağrıldığında, singleton hizmetlerinin ek bir kopyası oluşturulur. Bağımlılık enjeksiyon hizmetlerini 'Yapılandır' parametresi olarak alternatifler olarak düşünün.
Ebedi21

2
kullanımdan kaldırıldı IHostingEnvironment env bunun yerine IWebHostEnvironment env kullan
Mark Schultheiss

19

Bunu kod tabanınızda IHostingEnvironment'a kolay erişimi olmayan bir yerde test etmeniz gerekiyorsa, bunu yapmanın başka bir kolay yolu şöyledir:

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

iyi, kısa yol! Değişken adının "asp.net core" ve "asp.net" arasında farklı olduğunu unutmayın
nmDat

15

başına docs

ConfigureServices, {EnvironmentName} Yapılandırma ve {EnvironmentName} Hizmetlerini Yapılandırma formunun ortama özgü sürümlerini destekler:

Böyle bir şey yapabilirsiniz ...

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
}

1
Bu en güzel kongre
Stuart.Sklinar

11

Hizmetlerimden birinde çevreye sahip olmak istedim. Bunu yapmak gerçekten çok kolay! Ben sadece bu gibi yapıcı enjekte:

    private readonly IHostingEnvironment _hostingEnvironment;

    public MyEmailService(IHostingEnvironment hostingEnvironment)
    {
        _hostingEnvironment = hostingEnvironment;
    }

Şimdi daha sonra kodda bunu yapabilirim:

if (_hostingEnvironment.IsProduction()) {
    // really send the email.
}
else {
    // send the email to the test queue.
}

DÜZENLE:

Yukarıdaki kod .NET Core 2 içindir. Sürüm 3 için kullanmak isteyeceksiniz IWebHostEnvironment.


5

Barındırma ortamı, Başlangıç ​​sırasında IHostingEnvironment.IsEnvironment uzantı yöntemini veya IsDevelopment veya IsProduction'ın ilgili kolaylık yöntemlerinden birini kullanan ASPNET_ENV ortam değişkeninden gelir. İhtiyacınız olanı Başlangıç ​​() veya ConfigureServices çağrısına kaydedin:

var foo = Environment.GetEnvironmentVariable("ASPNET_ENV");

IHostingEnvironmentalanında kullanılamıyor ConfigureServices.
Muhammad Rehan Saeed

1
Hayır değil. Bununla nasıl başa çıkacağım konusundaki cevabıma geri dön.
Jeff Dunlop

8
Ortam değişkeni artık "ASPNETCORE_ENVIRONMENT"
Anthony

kullanımdan kaldırıldı IHostingEnvironment env bunun yerine IWebHostEnvironment env kullan
Mark Schultheiss

5

Birisinin de buna bakması durumunda. .Net core 3+ sürümünde bunların çoğu kullanılmıyor. Güncelleme yolu:

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

2

Dotnet Core 2.0'da, Başlangıç ​​kurucusu yalnızca bir IConfiguration parametresi bekler.

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

Orada barındırma ortamı nasıl okunur? ConfigureAppConfiguration sırasında Program sınıfında saklıyorum (WebHost.CreateDefaultBuilder yerine tam BuildWebHost kullanın):

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 sonra ConfigureServices böyle şöyle okur:

public IServiceProvider ConfigureServices(IServiceCollection services)
{
    var isDevelopment = Program.HostingEnvironment.IsDevelopment();
}

kullanımdan kaldırıldı IHostingEnvironment env bunun yerine IWebHostEnvironment env kullan
Mark Schultheiss
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.