web-dev-qa-db-ja.com

ASP.NET Coreの任意のクラスのConfigurationにアクセスする方法

私はASP.NETコアで 設定ドキュメント を実行しました。ドキュメントには、アプリケーションのどこからでも設定にアクセスできると書かれています。

以下はテンプレートによって作成されたStartup.csです。

public class Startup
{
    public Startup(IHostingEnvironment env)
    {
        var builder = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
            .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);

        if (env.IsEnvironment("Development"))
        {
            // This will Push telemetry data through Application Insights pipeline faster, allowing you to view results immediately.
            builder.AddApplicationInsightsSettings(developerMode: true);
        }

        builder.AddEnvironmentVariables();
        Configuration = builder.Build();
    }

    public IConfigurationRoot Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container
    public void ConfigureServices(IServiceCollection services)
    {
        // Add framework services.
        services.AddApplicationInsightsTelemetry(Configuration);

        services.AddMvc();
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline
    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        loggerFactory.AddConsole(Configuration.GetSection("Logging"));
        loggerFactory.AddDebug();

        app.UseApplicationInsightsRequestTelemetry();

        app.UseApplicationInsightsExceptionTelemetry();

        app.UseMvc();
    }
}

そのためStartup.csではすべての設定を構成し、Startup.csにはConfigurationという名前のプロパティもあります。

私はあなたがコントローラ内またはアプリケーション内の任意の場所でこの設定にどのようにアクセスするのか理解できないのですか? MSは options pattern を使用することを推奨していますが、キーと値のペアは4〜5しかないため、optionsパターンは使用しないでください。私はただアプリケーション内の設定にアクセスしたいと思いました。どのクラスにそれを注入するのですか?

82
LP13

更新

ASP.NET Core 2.0を使用すると、依存性注入コンテナーにアプリケーションのIConfigurationインスタンスが自動的に 追加されます 。これはConfigureAppConfigurationWebHostBuilderとも連動します。

例えば:

public static void Main(string[] args)
{
    var Host = WebHost.CreateDefaultBuilder(args)
        .ConfigureAppConfiguration(builder =>
        {
            builder.AddIniFile("foo.ini");
        })
        .UseStartup<Startup>()
        .Build();

    Host.Run();
}

IConfigurationインスタンスをConfigureServicesのシングルトンオブジェクトとしてサービスコレクションに追加するのと同じくらい簡単です。

public void ConfigureServices(IServiceCollection services)
{
   services.AddSingleton<IConfiguration>(Configuration);

   // ...
}

ConfigurationStartupクラスのインスタンスです。

これにより、任意のコントローラまたはサービスにIConfigurationを挿入できます。

public class HomeController
{
   public HomeController(IConfiguration configuration)
   {
      // Use IConfiguration instance
   }
}
113
Henk Mollema

私はこれが古いことを知っていますが、IOptionsパターンを実装するのが比較的簡単であるとすれば

  1. 設定内の設定に一致するパブリックなget/setプロパティを持つクラス

    public class ApplicationSettings
    {
        public string UrlBasePath { get; set; }
    }
    
  2. 設定を登録する

    public void ConfigureServices(IServiceCollection services)
    {
     ...
     services.Configure<ApplicationSettings>(Configuration.GetSection("ApplicationSettings"));
    ...
    }
    
  3. iOptionsを介して注入する

    public class HomeController
    {
       public HomeController(IOptions<ApplicationSettings> appSettings)
       { ...
        appSettings.Value.UrlBasePath
        ...
        // or better practice create a readonly private reference
        }
     }
    

どうしてあなたがこれをしないのか私にはわからない。

20
ScottC

正しいやり方:

.NET Coreでは、IConfigurationをパラメータとしてClassコンストラクタに注入することができ、それが利用可能になります。

public class MyClass 
{
    private IConfiguration configuration;
    public MyClass(IConfiguration configuration)
    {
        ConnectionString = new configuration.GetValue<string>("ConnectionString");
    }

クラスのインスタンスを作成したいとき、クラスがIConfigurationをインジェクトしているので、コンストラクタにIConfigurationパラメータを渡す必要があるので、new MyClass()を実行することはできません。クラスをインジェクションチェーンにもインジェクトするには、2つの簡単なステップが必要です。

1)Class/es - IConfigurationを使用する場所 - をStartup.csConfigureServices()メソッドのIServiceCollectionに追加します。

services.AddTransient<MyClass>();

2)インスタンスを定義します - Controllerの中で言って、コンストラクタを使ってそれを注入しましょう:

public class MyController : ControllerBase
{
    private MyClass _myClass;
    public MyController(MyClass myClass)
    {
        _myClass = myClass;
    }

今、あなたは自由にあなたの_myClass.configurationを楽しむことができるはずです...

他の選択肢:

クラスをコントローラにインジェクトしなくても利用できるようにする方法をまだ探している場合は、static classに格納できます。これはStartup.csに設定します。

public static class MyAppData
{
    public static IConfiguration Configuration;
}

Startupコンストラクタは次のようになります。

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

それからあなたのプログラムのどこかでMyAppData.Configurationを使ってください。

最初のオプションが正しい方法であることに私が直面しないでください。経験豊富な開発者は常に自分の道に沿ってゴミデータを避けているのを見ることができます。メモリ上で常に利用可能なデータの量は、パフォーマンスにとっても開発にとっても良くありませんし、そしてあなたが必要とするものだけを持っているほうがより安全かもしれません

6
Mayer Spitzer

私はオプションパターンのサンプルを調べて、これを見ました:

public class Startup
{
    public Startup(IConfiguration config)
    {
        // Configuration from appsettings.json has already been loaded by
        // CreateDefaultBuilder on WebHost in Program.cs. Use DI to load
        // the configuration into the Configuration property.
        Configuration = config;
    }
...
}

私のクラスのコンストラクタにIconfigurationを追加するとき、私はDIを通して設定オプションにアクセスすることができました。

例:

public class MyClass{

    private Iconfiguration _config;

    public MyClass(Iconfiguration config){
        _config = config;
    }

    ... // access _config["myAppSetting"] anywhere in this class
}
3
pursang

私は現時点ではこのようにやっています:

// Requires NuGet package Microsoft.Extensions.Configuration.Json

using Microsoft.Extensions.Configuration;
using System.IO;

namespace ImagesToMssql.AppsettingsJson
{
    public static class AppSettingsJson
    {           
        public static IConfigurationRoot GetAppSettings()
        {
            string applicationExeDirectory = ApplicationExeDirectory();

            var builder = new ConfigurationBuilder()
            .SetBasePath(applicationExeDirectory)
            .AddJsonFile("appsettings.json");

            return builder.Build();
        }

        private static string ApplicationExeDirectory()
        {
            var location = System.Reflection.Assembly.GetExecutingAssembly().Location;
            var appRoot = Path.GetDirectoryName(location);

            return appRoot;
        }
    }
}

それから、appsettings.jsonファイルからデータを取得する必要がある場所でこれを使用します。

var appSettingsJson = AppSettingsJson.GetAppSettings();
// appSettingsJson["keyName"]
2
Tadej

Startup.csでconfigurationをstaticにするオプションもありますので、どこからでも簡単にアクセスできるので、静的変数が便利です。

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

internal static IConfiguration Configuration { get; private set; }

これによりStartup.Configuration.GetSection...を使ってどこからでも設定にアクセスできるようになります。

2
konzo

マイクロソフトは8-2017年に.NET CORE v4.4のSystem.Configurationを発表しました。 現在v4.5 とv4.6のプレビュー。

.Net FrameworkからCOREへの変換に取り組んでいる私たちにとって、これは不可欠です。現在のapp.configファイルを保持して使用することができます。これは任意のアセンブリからアクセスできます。 Microsoftはその必要性を認識していたので、おそらくそれはappsettings.jsonの代わりになることさえ可能です。 FWでは以前と同じように機能します。違いが1つあります。

Webアプリケーションでは、 ASP.NET CORE WEB API]あなたのappSettingsまたはconfigurationSectionには、web.configではなくapp.configおよびではなくweb.configを使用する必要があります。 web.configを使用する必要があるかもしれませんが、IISを介してサイトをデプロイする場合に限られます。 IIS固有の設定をweb.configに配置します。

私はnetstandard20DLLとAsp.net Core Web Apiでテストしましたそしてそれはすべてうまくいっています。

0
T.S.