[C#] 윈폼에서 JSON을 이용해서 설정 기능을 쉽고, 간편하게 구현하기

제가 프로젝트를 할 때 항상 불러와서 쓰는 모듈 중에 하나입니다.

나름 테스트 열심히 해서 짜놨고, 필드에서 몇 년째 잘 써먹고 있습니다.

못난이 소스라 내놓기가 부끄럽지만, 안정성(?)은 보장된 것 같아서 올려봅니다^^;;

// 1. 프로그램 시작 시 => 설정을 불러온다.
config.load(); // throw exception 하므로 예외 처리 필요

// 2. 설정 항목을 불러와서 써먹을 때
btnOk.Width = config.instance.ELEMENT_BUTTON_FONT_SIZE;

// 3. 설정을 저장할 때
config.instance.ELEMENT_BUTTON_FONT_SIZE = 440;
// 변수에 할당 후에는 반드시 save() 호출!!해야 json에 write 
config.save(); // throw exception 하므로 예외 처리 필요

전체 소스입니다.

using System;
using System.Collections.Generic;
using System.IO;
using System.Text.Encodings.Web;
using System.Text.Json;
using System.Text.Unicode;
using System.Windows.Forms;

namespace ConfigHelper
{
    public class config
    {
        public static string FileName = "config";
        public class ConfigMember
        {
            public Enums.APP_TYPE APP_TYPE { get; set; } = Enums.APP_TYPE.SERVER;
            public string ELEMENT_BUTTON_FONT_NAME { get; set; } = "Segoe UI";
            public int ELEMENT_WIDTH { get; set; } = 465;
            public float ELEMENT_BUTTON_FONT_SIZE { get; set; } = 9;
            public System.Drawing.FontStyle ELEMENT_BUTTON_FONT_STYLE { get; set; }
            public bool USE_ADDITIONAL_TEXT1 { get; set; } = false;
            public List<ALARM_MEMBER> listAlarm { get; set; } = new List<ALARM_MEMBER>();
        }

        public static ConfigMember instance = new ConfigMember();
        /// <summary>
        /// 설정을 불러와 인스턴스에 보관한다
        /// </summary>
        public static void Load()
        {
            try
            {
                if (File.Exists($@"{Application.StartupPath}\{FileName}.json") == false)
                {
                    File.WriteAllText($@"{Application.StartupPath}\{FileName}.json", "{ }");
                }
                string jsonString = File.ReadAllText($@"{Application.StartupPath}\{FileName}.json");

                var options = new JsonSerializerOptions
                {
                    PropertyNameCaseInsensitive = true,
                };

                instance = JsonSerializer.Deserialize<ConfigMember>(jsonString);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// 인스턴스를 파일에 저장한다
        /// </summary>
        public static void Save()
        {
            try
            {
                JsonSerializerOptions options = new JsonSerializerOptions
                {
                    Encoder = JavaScriptEncoder.Create(UnicodeRanges.All),
                    PropertyNameCaseInsensitive = true,
                    WriteIndented = true
                };

                string json = JsonSerializer.Serialize(instance, options);
                File.WriteAllText($@"{Application.StartupPath}\{FileName}.json", json);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
    }
}

별 것 아닌 것 같지만, 진짜 별 것 아닙니다…ㅎㅎ

ConfigMember 제일 마지막 항목의 데이터 형식을 보면, List 형식으로 되어 있는 것을 보실 수 있습니다.

실제 저장되는 config.json의 파일을 열어보시면 GeneriC List에 들어있는 요소의 내부 Property도 다 저장됩니다.

{
  "APP_TYPE": 0,
  "ELEMENT_WIDTH": 920,
  "ELEMENT_BUTTON_FONT_NAME": "Segoe UI",
  "ELEMENT_BUTTON_FONT_SIZE": 14.25,
  "ELEMENT_BUTTON_FONT_COLOR": -1,
  "ELEMENT_BUTTON_FONT_STYLE": 1,
  
  "listClient": [
    {
      "IDX": null,
      "NAME": "1",
      "DISPLAY_NAME": "테스트1",
      "DESCRIPTION": "",
      "MQ_SUBSCRIBE_ADDRESS": "192.168.0.1:10000"
    },
    {
      "IDX": null,
      "NAME": "2",
      "DISPLAY_NAME": "테스트2",
      "DESCRIPTION": "",
      "MQ_SUBSCRIBE_ADDRESS": "192.168.0.2:10000"
    }
  ],
  "listAlarm": []
}

이런 식으로 데이터 형식을 가리지 않고 그냥 막 저장하고, 막 불러와서 쓸 수가 있습니다.
(float, int, bool, string, Enum, List 등등…)

instance 자체를 serialize/deserialize 하는 것이라서 별도의 데이터 형식 변환 절차가 없어서

저같은 귀차니스트한테는 안성맞춤입니다 ^^;;

좋아요 5