ConfigureServicesで開発/ステージング/本番ホスティング環境を取得する方法


170

ConfigureServicesスタートアップのメソッドで開発/ステージング/本番ホスティング環境を取得するにはどうすればよいですか?

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

このConfigureServicesメソッドは単一のIServiceCollectionパラメーターのみを受け取ります。


4
なぜIHostingEnvironmentConfigureServicesに注入できないのですか?見落とし?または私たちが知っておく必要がある理由は?
Simon_Weaver 2016年

回答:


225

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

13
docsによると、このメソッドは使用しないでください。代わりにを使用する必要がありますCurrentEnvironment.IsEnvironment("environmentname")
vaindil

28
またはCurrentEnvironment.IsDevelopment()/CurrentEnvironment.IsProduction()
Simon_Weaver

3
@vaindil-あなたが参照するドキュメントは、このメソッドが使用されるべきではないと言っていません。あなたの例は単に
大文字と小文字を

3
@ Coruscate5わかりました、このメソッドを使用しないことを明示的に言っていませんが、他のメソッドINSTEADを使用するように言っています。それは事実上同じです。
vaindil 2017年

8
非推奨のIHostingEnvironment envは代わりにIWebHostEnvironment envを使用してください
Mark Schultheiss

56

TL; DR

環境ASPNETCORE_ENVIRONMENTの名前で呼び出される環境変数を設定します(例:)Production。次に、次のいずれかを行います。

  • に注入IHostingEnvironmentStartup.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設定されている、2つの選択肢があります。

環境名を確認する

ドキュメントから

このIHostingEnvironmentサービスは、環境を操作するための中心的な抽象概念を提供します。このサービスはASP.NETホスティングレイヤーによって提供され、依存性注入を介してスタートアップロジックに注入できます。Visual StudioのASP.NET Core Webサイトテンプレートは、このアプローチを使用して、環境固有の構成ファイル(存在する場合)を読み込み、アプリのエラー処理設定をカスタマイズします。どちらの場合も、この動作は、適切なメソッドに渡されたのインスタンス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()StartupConfigure{EnvironmentName}()Configure{EnvironmentName}Services()ConfigureDevelopment()Configure()ConfigureDevelopmentServices()ConfigureServices()


29

では.NET Core 2.0MVCアプリ/Microsoft.AspNetCore.All v2.0.0デベロッパー、あなたは@vaindilによって記載されているように、環境固有のスタートアップクラスを持つことができますが、私はそのアプローチが好きではありません。

あなたはまた、注入することができIHostingEnvironmentStartUpコンストラクタ。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());
            }            
        });

        ......
    }
}


ここではアンドレによって投稿英語のリンクは次のとおりです。docs.microsoft.com/en-us/aspnet/core/fundamentals/...
ahong

1
非推奨のIHostingEnvironment envは代わりにIWebHostEnvironment envを使用してください
Mark Schultheiss

21

これは、次のように追加のプロパティやメソッドパラメータなしで実現できます。

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

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

2
史上最高の答え。thanx
Shady Sherif

7
これにより、.NET Core 3.0では次の警告がスローされます。アプリケーションコードから「BuildServiceProvider」を呼び出すと、シングルトンサービスの追加のコピーが作成されます。'Configure'のパラメーターとして依存性注入サービスなどの代替手段を検討してください。
Eternal21

2
非推奨のIHostingEnvironment envは代わりにIWebHostEnvironment envを使用してください
Mark Schultheiss

19

IHostingEnvironmentに簡単にアクセスできないコードベースのどこかでこれをテストする必要がある場合、別の簡単な方法は次のとおりです。

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

まあ、短い道!「asp.net core」と「asp.net」では変数名が異なることに
注意してください

14

ドキュメントごと

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
}

これは最も素晴らしい大会です
Stuart.Sklinar

11

私は自分のサービスの1つに環境を取り入れたかったのです。とても簡単です!私はそれを次のようにコンストラクタに注入するだけです:

    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 Core 2用IWebHostEnvironmentです。バージョン3の場合はを使用します。


5

ホスティング環境は、ASPNET_ENV環境変数から取得されます。ASPNET_ENV環境変数は、IHostingEnvironment.IsEnvironment拡張メソッド、またはIsDevelopmentまたはIsProductionの対応する便利なメソッドの1つを使用して起動時に使用できます。必要なものをStartup()に保存するか、ConfigureServices呼び出しに保存します。

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

IHostingEnvironmentでは利用できませんConfigureServices
Muhammad Rehan Saeed

1
いいえ、ちがいます。対処方法については、私の回答を参照してください。
ジェフダンロップ

8
環境変数は「ASPNETCORE_ENVIRONMENT」になりました
Anthony

非推奨のIHostingEnvironment envは代わりにIWebHostEnvironment envを使用してください
Mark Schultheiss

5

誰かがこれも探している場合に備えて。.net core 3+では、これのほとんどは廃止されています。更新方法は次のとおりです。

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では、Startup-constructorはIConfiguration-parameterのみを想定しています。

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

そこでホスティング環境を読むには?ConfigureAppConfiguration中にProgram-classに保存します(WebHost.CreateDefaultBuilderの代わりに完全なBuildWebHostを使用します)。

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 envは代わりにIWebHostEnvironment envを使用してください
Mark Schultheiss
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.