[C#] ASP.NET Core의 모든 클래스에서 구성에 액세스하려면 어떻게하나요?

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는 옵션 패턴 사용 권장 하지만 키-값 쌍이 4 ~ 5 개만 있으므로 옵션 패턴을 사용하지 않으려 고합니다. 응용 프로그램에서 구성에 액세스하고 싶었습니다. 수업에 어떻게 주입합니까?



답변

최신 정보

ASP.NET Core 2.0을 사용 하면 종속성 주입 컨테이너에 애플리케이션 의 인스턴스 가 자동으로 추가 됩니다IConfiguration . 이것은에서와 함께 작동 ConfigureAppConfiguration합니다 WebHostBuilder.

예를 들면 :

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

   // ...
}

클래스 Configuration의 인스턴스는 어디에 있습니까 Startup?

이를 통해 IConfiguration모든 컨트롤러 또는 서비스 에 삽입 할 수 있습니다 .

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


답변

이를 수행하는 올바른 방법 :

.NET Core에서는 IConfiguration클래스 생성자에 매개 변수로를 삽입 할 수 있으며 사용할 수 있습니다.

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

당신이 당신의 클래스가 주입됩니다 이후, 클래스의 인스턴스를 생성 할 때 지금 IConfiguration, 당신은 할 수 없습니다 new MyClass()그것이 필요하기 때문에, IConfiguration매개 변수는 생성자에 주입 그래서, 당신은 귀하의 클래스를 주입해야합니다, 주입 체인에 잘 맞습니다. 이는 두 가지 간단한 단계를 의미합니다.

당신은을 사용하려면 – 1) 클래스 / ES를 추가 IConfiguration받는 사람, IServiceCollection상기 ConfigureServices()방법Startup.cs

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프로그램의 어느 곳에서나 사용 하십시오.

첫 번째 옵션이 올바른 방법 인 이유를 대면하지 마십시오. 경험 많은 개발자가 항상 쓰레기 데이터를 피하는 것을 볼 수 있습니다. 항상 메모리에 많은 양의 데이터를 사용할 수있는 것이 최선의 방법이 아니라는 것은 잘 알고 있습니다. 성능이나 개발에도 좋지 않으며 필요한 것만 가지고있는 것이 더 안전 할 수도 있습니다.


답변

나는 이것이 오래되었다는 것을 알고 있지만 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
        }
     }

왜 그렇게하지 않는지 모르겠습니다.


답변

나는 지금 이렇게하고있다.

// 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"]


답변

또한 configurationstartup.cs에 정적 으로 만들 수있는 옵션이있어서 어디서든 쉽게 액세스 할 수 있습니다. 정적 변수는 편리합니다.

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

internal static IConfiguration Configuration { get; private set; }

이렇게하면 Startup.Configuration.GetSection...What can go wrong?을 사용하여 어디서나 구성에 액세스 할 수 있습니다.


답변

옵션 패턴 샘플을 살펴보고 다음을 보았습니다.

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
}


답변

이 작업을 수행하는 여러 가지 방법이있을 수 있다는 것을 알고 있으며 Core 3.1을 사용하고 있으며 최적 / 깨끗한 옵션을 찾고 있었고 결국 이렇게했습니다.

  1. 내 시작 클래스는 기본값입니다.
public Startup(IConfiguration configuration)
{
    Configuration = configuration;
}

public IConfiguration Configuration { get; }

// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers();
}
  1. 내 appsettings.json은 다음과 같습니다.
{
  "CompanySettings": {
    "name": "Fake Co"
  }
}
  1. 내 클래스는 API 컨트롤러이므로 먼저 using 참조를 추가 한 다음 IConfiguration 인터페이스를 삽입했습니다.
using Microsoft.Extensions.Configuration;

public class EmployeeController
{
    private IConfiguration _configuration;
    public EmployeeController(IConfiguration configuration)
    {
        _configuration = configuration;
    }
}
  1. 마지막으로 GetValue 메서드를 사용했습니다.
public async Task<IActionResult> Post([FromBody] EmployeeModel form)
{
    var companyName = configuration.GetValue<string>("CompanySettings:name");
    // companyName = "Fake Co"
}