استفاده از فایل Json برای ذخیره و بازیابی تنظیمات برنامه
اندازه‌ی قلم متن
تخمین مدت زمان مطالعه‌ی مطلب: سه دقیقه

قطعا شرایطی پیش خواهد آمد که شما مجبور شوید داده‌هایی را به عنوان تنظیمات برنامه در محلی ذخیره کنید و مجددا آن‌ها را فراخوانی کنید. روش‌های مختلفی برای این کار وجود دارند که معروف‌ترین و ساده‌ترین راه، استفاده از Settings خود پروژه می‌باشد. اما این به منزله بهترین راه نیست! در این مطلب قصد داریم تنظیمات برنامه را در یک فایل json، با همان ساختار استانداردش ذخیره و بازیابی کنیم.
برای اینکار نیاز به سریالایز و دیسریالایز کردن مدل داریم. اگر از دات نت کور استفاده میکنید، کتابخانه توکار جیسون، در فضای نام System.Text.Json از عهده این کار بر میاد و اگر از نسخه‌های دات نت فریمورک استفاده میکنید، باید پکیج newtonsoft.json را نصب کنید.
برای شروع یک کلاس را به نام GlobalData (یا هر نام دلخواه دیگری) ایجاد کنید.
چون قرار هست این کلاس هر نوع مدلی را برای ما سریالایز و دیسریالایز کند، پس کلاس را بصورت جنریک تعریف کنید.
public abstract class GlobalData<T> where T : GlobalData<T>, new()
حالا برای دسترسی به این کلاس، یک متغیر جنریک را به نام Config ایجاد میکنیم:
public static T Config { get; set; }
همینطور برای خواندن یک فایل جیسون از محلی مشخص، یک متغیر دیگر را به نام filename ایجاد میکنیم:
private static string _filename { get; set; }
در این کلاس به 2 متد نیاز داریم. متد اول برای دیسریالایز کردن فایل جیسون و متد دوم برای سریالایز کردن اطلاعات:
public static void Init(string FileName = "AppConfig.json")
        {
            _filename = FileName;
            if (File.Exists(FileName))
            {
                string json = File.ReadAllText(FileName);

                Config = (string.IsNullOrEmpty(json) ? new T() : JsonSerializer.Deserialize<T>(json)) ?? new T();
            }
            else
            {
                Config = new T();
            }
        }
بصورت پیشفرض محل خواندن فایل جیسون را در کنار فایل اجرایی exe و با نام AppConfig.json در نظر میگیریم. در صورتی که فایل ما موجود بود، به کمک ReadAllText محتوای فایل جیسون را میخوانیم و در صورتی که خالی نبود، اقدام به دیسریالایز کردن آن میکنیم.
در متد Save نیز:
public static void Save()
        {
            JsonSerializerOptions options = new JsonSerializerOptions { WriteIndented = true, IgnoreNullValues = true };

            string json = JsonSerializer.Serialize(Config, options);
            File.WriteAllText(_filename, json);
        }
پراپرتی Config را که شامل اطلاعات ما میباشد، در محل موردنظر سریالایز میکنیم.
حالا به سراغ پروژه‌ی دمو می‌رویم. یک کلاس را ایجاد کرده و از کلاس GlobalData ارث بری میکنیم:
internal class AppConfig : GlobalData<AppConfig>
حالا پراپرتی‌های دلخواه خود را ایجاد میکنیم:
 public string ServerUrl { get; set; } = "https://sub.deltaleech.com";
 public bool IsShowNotification { get; set; } = true;
 public NavigationViewPaneDisplayMode PaneDisplayMode { get; set; } = NavigationViewPaneDisplayMode.Left;

 public SkinType Skin { get; set; } = SkinType.Default;
دقت کنید که قبل از خواندن تنظیمات، باید ابتدا فایل تنظیمات را دیسریالایز کرده باشید. پس هنگام اجرای پروژه، متد Init را فراخوانی کنید:
protected override void OnStartup(StartupEventArgs e) {
GlobalData<AppConfig>.Init();
}
برای خواندن تنظیمات به این صورت عمل کنید:
var skin = GlobalData<AppConfig>.Config.Skin;
و برای ذخیره کردن :
GlobalData<AppConfig>.Config.Skin = Skin.Dark;
GlobalData<AppConfig>.Save();

دقت داشته باشید که اگر بعد از ذخیره کردن تنظیمات، قصد داشته باشید اطلاعات جدید را دریافت کنید، باید حتما قبل از دریافت اطلاعات، متد Init را یکبار دیگر فراخوانی کنید تا اطلاعات جدید، نمایش داده شود.

  • #
    ‫۳ سال و ۷ ماه قبل، یکشنبه ۲۸ دی ۱۳۹۹، ساعت ۲۲:۲۴
    اگر داخل appsetting.json ذخیره کنیم ، چند تا امتیاز داره : 
    اول از همه اینکه میتونیم تنظیمات رو با استفاده از قابلیت‌های dependency injection به کلاس‌های مرتبط اضافه کنیم و اون کلاس رو به صورت یک dependency service استفاده کنیم.
    دوم اینکه میتونیم از قابلیت‌های environment تو کار دات نت استفاده کنیم و مقادیر متفاوت رو لحاظ کنیم.
    نقص عمده این روش فقط میتونیم از بین primitive data type‌ها نوع‌های reference type مثل string رو استفاده کنیم.