What is the prefered way for persisting user settings for WPF applications with .Net Core >=3.0?
Created WPF .Net Core 3.0 Project (VS2019 V16.3.1) Now I have seen t
Based on Funk's answer here's an abstract generic singleton-style variation that removes some of the administration around SettingsManager and makes creating additional settings classes and using them as simple as possible:
Typed Settings class:
//Use System.Text.Json attributes to control serialization and defaults
public class MySettings : SettingsManager
{
public bool SomeBoolean { get; set; }
public string MyText { get; set; }
}
Usage:
//Loading and reading values
MySettings.Load();
var theText = MySettings.Instance.MyText;
var theBool = MySettings.Instance.SomeBoolean;
//Updating values
MySettings.Instance.MyText = "SomeNewText"
MySettings.Save();
As you can see the number of lines to create and use your settings are just as minimal, and a bit more rigid as there are no parameters.
The base class defines where settings are stored and allows only for one settings file per MySettings subclass - assembly and class names determine its location. For the purpose of replacing a properties file that is enough.
using System;
using System.IO;
using System.Linq;
using System.Reflection;
public abstract class SettingsManager where T : SettingsManager, new()
{
private static readonly string filePath = GetLocalFilePath($"{typeof(T).Name}.json");
public static T Instance { get; private set; }
private static string GetLocalFilePath(string fileName)
{
string appData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
var companyName = Assembly.GetEntryAssembly().GetCustomAttributes().FirstOrDefault();
return Path.Combine(appData, companyName?.Company ?? Assembly.GetEntryAssembly().GetName().Name, fileName);
}
public static void Load()
{
if (File.Exists(filePath))
Instance = System.Text.Json.JsonSerializer.Deserialize(File.ReadAllText(filePath));
else
Instance = new T();
}
public static void Save()
{
string json = System.Text.Json.JsonSerializer.Serialize(Instance);
Directory.CreateDirectory(Path.GetDirectoryName(filePath));
File.WriteAllText(filePath, json);
}
}
Some improvements might be made in disabling the constructor of the settings subclass and creation of SettingsManager
without Load()ing it; that depends on your own use cases.