142 lines
4.2 KiB
C#
142 lines
4.2 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using Newtonsoft.Json;
|
|
using Newtonsoft.Json.Serialization;
|
|
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;
|
|
}
|
|
}
|
|
} |