Skip to content

커스텀 섹션 작성

NeoDEEX.Configuration 네임스페이스는 구성 설정 내에 사용자의 커스텀 섹션을 읽고 관리할 수 있는 베이스 클래스들을 제공합니다. 다음 두 클래스를 사용하여 사용자 정의 섹션을 읽고 관리할 수 있습니다.

  • FoxConfigurationSection
  • FoxConfiguration<T>

Fox Data Access나 Fox Biz/Data Service와 같은 다른 NeoDEEX의 기능들도 이들 두 클래스를 사용하여 "database", "foxbizservice" 구성 설정을 관리합니다.

FoxConfigurationSection 클래스

FoxConfigurationSection 클래스는 NeoDEEX 구성 설정 파일(neodeex.config.json) 파일의 최 상위 섹션에 매핑되어 구성 설정을 읽어 들입니다. 또한 이 클래스는 구성 설정 파일이 변경되면 자동으로 변경된 구성 설정을 읽어 들여 최신화하는 기능도 제공합니다.

Fox Configuration 기능은 내부적으로 Microsoft.Extension.Configuration 기능을 사용합니다. 따라서 FoxConfigurationSection 클래스를 이용하여 구성 설정을 제어하기 위해서는 IConfiguration, IConfigurationSection 인터페이스 등의 기능에 익숙해야 합니다. 이 문서는 독자들이 이들 클래스의 사용법에 대해 알고 있다고 가정하며 상세한 설명을 하지 않습니다.

객체 생성

구성 설정 섹션에 접근하기 위해서는 FoxConfigurationSection 객체를 생성해야 합니다. 생성자의 매개변수로 섹션의 이름을 설정하면 됩니다.

{
  "mySettings": {
    "stringProp": "StringValue1",
    "boolProp": false,
    "stringList": [ "str1", "str2", "str3", "str4" ],
    "subObject": {
      "name": "myName",
      "value":  "myValue"
    }
  }
}
var section = new FoxConfigurationSection("mySettings");

위 코드는 구성 설정에서 "mySettings" 섹션과 FoxConfigurationSection 객체를 연결합니다. 이제 FoxConfigurationSection 객체를 통해 "mySettings" 접근이 가능합니다.

ConfigSection 속성

FoxConfigurationSection 클래스는 IConfigurationSection 인터페이스를 반환하는 ConfigSection 속성을 제공합니다. 이 속성을 통해 구성 설정을 읽을 수 있습니다.

var strValue = section.ConfigSection["stringProp"];
Console.WriteLine($"stringProp={strValue}");

다음 예제는 "subObject" 키를 하위 섹션으로 읽어 IConfigurationSection 객체를 읽는 예를 보여 줍니다.

IConfigurationSection subObject = section.ConfigSection.GetSection("subObject");
Console.WriteLine($"name: {subObject["name"]}");

오류 처리

"mySettings" 섹션이 존재하지 않더라도 위 코드는 오류를 유발하지 않습니다. 즉, FoxConfigurationSection.ConfigSection 속성이 null이 아닙니다. 다만 ConfiguSection 속성을 통해 구성 설정에 접근하더라도 결과값으로 null 혹은 빈 문자열(String.Empty)을 반환합니다.

주어진 섹션이 존재하지 않을 때 예외가 발생하길 원한다면 생성자에 추가적인 예외 발생 옵션을 명시하십시요. 이 경우, 섹션이 존재하지 않는 경우 FoxInvalidConfigurationException이 발생할 것입니다.

var section = new FoxConfigurationSection("nonExistSectionName", true); 
var value = section.ConfigSection["stringProp"];
1
2
3
4
5
Unhandled exception. NeoDEEX.Configuration.FoxInvalidConfigurationException: Invalid configuration found when intializing 'nonExistSectionName' section. It is caused from invalid configuration JSON. Detail Message: The "nonExistSectionName" section is not found..
 ---> NeoDEEX.Configuration.FoxInvalidConfigurationException: The "nonExistSectionName" section is not found.
   at NeoDEEX.Configuration.FoxConfigurationBuilder.GetConfigSection(String sectionName, Boolean throwOnError)
   at NeoDEEX.Configuration.FoxConfigurationSection.OnInitialize()
   ......

기타 속성

FoxConfigurationSection 클래스는 앞서 언급한 ConfigSection 속성 이외에도 몇가지 속성을 제공합니다.

  • IsEmpty 속성

이 속성은 FoxConfigurationSection 객체로 연결된 구성 설정 섹션이 존재하지 않거나 아무런 설정도 없는 경우 true를 반환합니다.

  • SectionName 속성

FoxConfigurationSection 객체가 연결된 구성 설정 섹션 이름을 반환합니다.

FoxConfiguration<T> 클래스

FoxConfiguration<T> 클래스는 FoxConfigurationSection 클래스에서 파생된 클래스로서 구성 설정 섹션과 닷넷 타입 T를 바인딩합니다.

위에서 보인 "mySettings" 섹션은 다음 클래스로 바인딩 할 수 있습니다.

internal class MySettings
{
    public string? StringProp { get; set; }
    public bool? BoolProp { get; set; }
    public List<string> StringList { get; set; } = new();
    public SubType? SubObject { get; set; }
}

internal class SubType
{
    public string? Name { get; set;}
    public string? Value { get; set; } = "DefaultValue";
}

"mySettings" 섹션을 MySettings 클래스로 바인딩 하기 위해서는 FoxConfiguration<MySettings> 객체를 생성합니다. 섹션이 존재하지 않을 때 오류를 유발하고자 한다면 FoxConfigurationSection 클래스와 마찬가지로 생성자에 추가적으로 매개변수 true를 추가하십시요.

var section = new FoxConfiguration<MySettings>("mySettings");

Section 속성

바인딩된 객체에 접근하기 위해서는 Section 속성을 사용합니다. Section 속성은 FoxConfiguration<T> 클래스의 T 타입의 객체(이 예제의 경우 MySettings 타입의 객체)를 반환합니다.

1
2
3
MySettings mySettings = section.Section;
Console.WriteLine(mySettings.StringProp);       // StringValue1 출력
Console.WriteLine(mySettings.SubObject.Value);  // myValue 출력

FoxConfiguration<T> 객체와 연결된 구성 설정 섹션이 존재하지 않는 경우(예외 발생 매개변수가 false인 경우)에도 Section 속성은 null을 반환하지 않고 T 타입의 객체를 반환합니다. 이 경우, 반환되는 객체는 구성 설정이 전혀 반영되지 않은 기본값들만 포함하게 됩니다. 위 바인딩 예제는 MySettings.StringValue 속성은 null 값이며, MySettings.SubType.Value 속성은 DefaultValue 값을 가집니다.

지연 초기화

FoxConfigurationSection 및 그 파생 클래스들은 구성 설정 파일에 대한 접근을 최대한 뒤로 미룹니다. 즉, FoxConfigurationSection 객체를 생성하더라도 구성 설정 파일로부터 구성 설정을 곧바로 읽지 않고 실제 구성 설정 값에 최초로 접근할 때 구성 설정을 읽어 들입니다. 이는 전역적으로 결정되므로 이미 구성 설정이 읽혀 들인 후에 FoxConfigurationSection 객체를 생성하면 읽혀진 구성 설정으로부터 FoxConfigurationSection 객체가 초기화 됩니다.

변경 감지

FoxConfigurationSection 및 그 파생 클래스들은 구성 설정 파일에 변경이 감지되면 FoxConfigurationManager로부터 통지를 받게 되며 초기화 되지 않은 상태로 리셋됩니다.

이 이후, 최초의 구성 설정 접근이 발생하면 구성 설정 파일을 읽어들이며 FoxConfigurationSection 객체가 초기화 됩니다.

고급 구성 설정 커스터마이징

지금까지 예제로 사용한 "mySettings" 섹션과 같이 단순하게 설정 값을 사용하거나 MySetting 클래스와 같이 정적인 클래스에 바인딩하고자 하는 경우, FoxConfigurationSection 클래스와 FoxConfiguration<T> 클래스 대신 FoxConfigurationManager.AppSettings 속성을 통해 FoxConfigurationAppSettings 클래스를 사용하는 것이 더 편리합니다. FoxConfigurationAppSettings 클래스는 하위 설정을 허용하며 구성 설정 파일 변경 시 변경된 값을 읽어 들일 수 있기 때문입니다.

FoxConfigurationAppSettings 클래스는 내부적으로 FoxConfigurationSection 객체를 사용합니다. 이는 이 클래스가 IConfigurationSection 인터페이스를 직접 노출하지 않고 편리한 몇몇 속성/메서드만을 제공하기 위함입니다. 이처럼 동적인 구성 설정 기능을 제공해야 하거나, 바인딩 시 구성 설정 이름과 속성 이름을 동일하게 가져갈 수 없을 때 등의 상황에서는 FoxConfigurationSection 클래스에서 파생된 클래스를 정의하고 OnInitialize 메서드를 오버라이드 해야 할 수도 있습니다.

이 문서는 OnInitialize 메서드 오버라이드와 같은 고급 구성 설정 방법을 다루지 않습니다. 구체적인 예제는 CustomSection 예제를 참조 하십시요.