Files
Pilz/Pilz.Configuration/SettingsManager.cs
2024-06-05 19:15:32 +02:00

139 lines
3.7 KiB
C#

using Newtonsoft.Json;
using System;
using System.IO;
using ErrorEventArgs = Newtonsoft.Json.Serialization.ErrorEventArgs;
namespace Pilz.Configuration;
public class SettingsManager : ISettingsManager
{
public event EventHandler AutoSavingSettings;
public event EventHandler SavingSettings;
public event EventHandler SavedSettings;
public event EventHandler<ErrorEventArgs> OnSerializationError;
protected ISettings defaultInstance = null;
protected bool enableAutoSave = false;
protected bool addedHandler = false;
public string ConfigFilePath { get; set; }
public ISettings Instance
{
get
{
if (defaultInstance is null)
Load();
return defaultInstance;
}
}
public bool AutoSaveOnExit
{
get => enableAutoSave;
set
{
if (enableAutoSave != value)
{
enableAutoSave = value;
if (enableAutoSave)
{
if (!addedHandler)
AddAutoSaveHandler();
}
else
{
if (addedHandler)
RemoveAutoSaveHandler();
}
}
}
}
public SettingsManager()
{
}
public SettingsManager(string fileName, bool autoSaveOnExit) : this()
{
ConfigFilePath = fileName;
AutoSaveOnExit = autoSaveOnExit;
}
protected void AddAutoSaveHandler()
{
AppDomain.CurrentDomain.ProcessExit += AutoSaveSettingsOnExit;
addedHandler = true;
}
protected void RemoveAutoSaveHandler()
{
AppDomain.CurrentDomain.ProcessExit -= AutoSaveSettingsOnExit;
addedHandler = false;
}
private void AutoSaveSettingsOnExit(object sender, EventArgs e)
{
AutoSavingSettings?.Invoke(this, new EventArgs());
Save();
}
public void Save()
{
if (!string.IsNullOrEmpty(ConfigFilePath) && defaultInstance is not null)
SaveInternal();
}
public void Load()
{
if (!string.IsNullOrEmpty(ConfigFilePath) && File.Exists(ConfigFilePath))
LoadInternal();
else
CreateNewInstance();
}
public void Reset()
{
Instance.Reset();
}
protected virtual void CreateNewInstance()
{
defaultInstance = new Settings();
defaultInstance.Reset();
}
protected virtual void LoadInternal()
{
defaultInstance = JsonConvert.DeserializeObject<Settings>(File.ReadAllText(ConfigFilePath), CreateJsonSerializerSettings());
}
protected virtual void SaveInternal()
{
SavingSettings?.Invoke(this, EventArgs.Empty);
File.WriteAllText(ConfigFilePath, JsonConvert.SerializeObject(defaultInstance, CreateJsonSerializerSettings()));
SavedSettings?.Invoke(this, EventArgs.Empty);
}
protected virtual JsonSerializerSettings CreateJsonSerializerSettings()
{
return new JsonSerializerSettings()
{
Formatting = Formatting.Indented,
TypeNameHandling = TypeNameHandling.Auto,
Error = JsonSerializer_OnError,
};
}
protected virtual void JsonSerializer_OnError(object sender, ErrorEventArgs e)
{
const string errorResolvingType = "Error resolving type specified in JSON";
// Invoke event
OnSerializationError?.Invoke(sender, e);
// Handle ourself
if (!e.ErrorContext.Handled && e.ErrorContext.Error is JsonSerializationException serializationException && serializationException.Message.StartsWith(errorResolvingType))
e.ErrorContext.Handled = true;
}
}