convert to C# & update config system

This commit is contained in:
2024-01-10 09:07:40 +01:00
parent 26d56f3e88
commit 0c0c5e82bc
24 changed files with 657 additions and 610 deletions

View File

@@ -0,0 +1,87 @@
using System;
namespace Pilz.Configuration
{
public class AutoSaveConfigurationManager : ConfigurationManager
{
private bool addedHandler = false;
private bool enableAutoSave = false;
private string _ConfigFilePath = string.Empty;
private bool _AutoLoadConfigOnAccess = false;
public string ConfigFilePath
{
get => _ConfigFilePath;
set
{
_ConfigFilePath = value;
if (AutoLoadConfigOnAccess)
Load();
}
}
public bool AutoLoadConfigOnAccess
{
get => _AutoLoadConfigOnAccess;
set
{
_AutoLoadConfigOnAccess = value;
if (value)
Load();
}
}
public bool AutoSaveConfigOnExit
{
get => enableAutoSave;
set
{
if (enableAutoSave != value)
{
enableAutoSave = value;
if (enableAutoSave)
AddAutoSaveHandler();
else
RemoveAutoSaveHandler();
}
}
}
private void AddAutoSaveHandler()
{
if (!addedHandler)
{
AppDomain.CurrentDomain.ProcessExit += AutoSaveSettingsOnExit;
addedHandler = true;
}
}
private void RemoveAutoSaveHandler()
{
AppDomain.CurrentDomain.ProcessExit -= AutoSaveSettingsOnExit;
addedHandler = false;
}
private void AutoSaveSettingsOnExit(object sender, EventArgs e)
{
Save();
}
private void Save()
{
if (!string.IsNullOrEmpty(ConfigFilePath) && Configuration is not null)
Configuration.WriteToFile(ConfigFilePath);
}
private void Load()
{
if (!string.IsNullOrEmpty(ConfigFilePath))
Configuration.ReadFromFile(ConfigFilePath);
}
~AutoSaveConfigurationManager()
{
RemoveAutoSaveHandler();
}
}
}

View File

@@ -1,78 +0,0 @@
Public Class AutoSaveConfigurationManager
Inherits ConfigurationManager
Private addedHandler As Boolean = False
Private enableAutoSave As Boolean = False
Private _ConfigFilePath As String = String.Empty
Private _AutoLoadConfigOnAccess As Boolean = False
Public Property ConfigFilePath As String
Get
Return _ConfigFilePath
End Get
Set
_ConfigFilePath = Value
If AutoLoadConfigOnAccess Then Load()
End Set
End Property
Public Property AutoLoadConfigOnAccess As Boolean
Get
Return _AutoLoadConfigOnAccess
End Get
Set
_AutoLoadConfigOnAccess = Value
If Value Then Load()
End Set
End Property
Public Property AutoSaveConfigOnExit As Boolean
Get
Return enableAutoSave
End Get
Set
If enableAutoSave <> Value Then
enableAutoSave = Value
Select Case enableAutoSave
Case True
AddAutoSaveHandler()
Case False
RemoveAutoSaveHandler()
End Select
End If
End Set
End Property
Private Sub AddAutoSaveHandler()
If Not addedHandler Then
AddHandler AppDomain.CurrentDomain.ProcessExit, AddressOf AutoSaveSettingsOnExit
addedHandler = True
End If
End Sub
Private Sub RemoveAutoSaveHandler()
RemoveHandler AppDomain.CurrentDomain.ProcessExit, AddressOf AutoSaveSettingsOnExit
addedHandler = False
End Sub
Private Sub AutoSaveSettingsOnExit(sender As Object, e As EventArgs)
Save()
End Sub
Private Sub Save()
If Not String.IsNullOrEmpty(ConfigFilePath) AndAlso Configuration IsNot Nothing Then
Configuration.WriteToFile(ConfigFilePath)
End If
End Sub
Private Sub Load()
If Not String.IsNullOrEmpty(ConfigFilePath) Then
Configuration.ReadFromFile(ConfigFilePath)
End If
End Sub
Protected Overrides Sub Finalize()
RemoveAutoSaveHandler()
End Sub
End Class

View File

@@ -0,0 +1,12 @@
namespace Pilz.Configuration
{
public abstract class ConfigurationManager
{
public SimpleConfiguration Configuration { get; private set; }
internal void SetConfiguration(SimpleConfiguration configuration)
{
Configuration = configuration;
}
}
}

View File

@@ -1,9 +0,0 @@
Public MustInherit Class ConfigurationManager
Public ReadOnly Property Configuration As SimpleConfiguration
Friend Sub SetConfiguration(configuration As SimpleConfiguration)
_Configuration = configuration
End Sub
End Class

View File

@@ -0,0 +1,88 @@
using System.Collections;
using System.Collections.Generic;
using Pilz.GeneralEventArgs;
namespace Pilz.Configuration
{
public class ConfigurationManagerList : IList<ConfigurationManager>
{
public event GettingParentManagerEventHandler GettingParentManager;
public delegate void GettingParentManagerEventHandler(object sender, GetValueEventArgs<SimpleConfiguration> e);
private readonly List<ConfigurationManager> myList = new List<ConfigurationManager>();
private object GetParentManager()
{
var args = new GetValueEventArgs<SimpleConfiguration>();
GettingParentManager?.Invoke(this, args);
return args.Value;
}
public ConfigurationManager this[int index]
{
get => myList[index];
set => myList[index] = value;
}
public int Count => myList.Count;
public bool IsReadOnly => false;
public void Insert(int index, ConfigurationManager item)
{
myList.Insert(index, item);
item.SetConfiguration((SimpleConfiguration)GetParentManager());
}
public void RemoveAt(int index)
{
}
public void Add(ConfigurationManager item)
{
item.SetConfiguration((SimpleConfiguration)GetParentManager());
}
public void Clear()
{
foreach (ConfigurationManager item in myList)
item.SetConfiguration(null);
myList.Clear();
}
public void CopyTo(ConfigurationManager[] array, int arrayIndex)
{
myList.CopyTo(array, arrayIndex);
}
public int IndexOf(ConfigurationManager item)
{
return myList.IndexOf(item);
}
public bool Contains(ConfigurationManager item)
{
return myList.Contains(item);
}
public bool Remove(ConfigurationManager item)
{
item.SetConfiguration(null);
return myList.Remove(item);
}
public IEnumerator<ConfigurationManager> GetEnumerator()
{
return (IEnumerator<ConfigurationManager>)IEnumerable_GetEnumerator();
}
private IEnumerator IEnumerable_GetEnumerator()
{
return myList.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator() => IEnumerable_GetEnumerator();
}
}

View File

@@ -1,83 +0,0 @@
Imports Pilz.Configuration
Imports Pilz.GeneralEventArgs
Public Class ConfigurationManagerList
Implements IList(Of ConfigurationManager)
Public Event GettingParentManager(sender As Object, e As GetValueEventArgs(Of SimpleConfiguration))
Private ReadOnly myList As New List(Of ConfigurationManager)
Private Function GetParentManager()
Dim args As New GetValueEventArgs(Of SimpleConfiguration)
RaiseEvent GettingParentManager(Me, args)
Return args.Value
End Function
Default Public Property Item(index As Integer) As ConfigurationManager Implements IList(Of ConfigurationManager).Item
Get
Return myList(index)
End Get
Set(value As ConfigurationManager)
myList(index) = value
End Set
End Property
Public ReadOnly Property Count As Integer Implements ICollection(Of ConfigurationManager).Count
Get
Return myList.Count
End Get
End Property
Public ReadOnly Property IsReadOnly As Boolean Implements ICollection(Of ConfigurationManager).IsReadOnly
Get
Return False
End Get
End Property
Public Sub Insert(index As Integer, item As ConfigurationManager) Implements IList(Of ConfigurationManager).Insert
myList.Insert(index, item)
item.SetConfiguration(GetParentManager)
End Sub
Public Sub RemoveAt(index As Integer) Implements IList(Of ConfigurationManager).RemoveAt
End Sub
Public Sub Add(item As ConfigurationManager) Implements ICollection(Of ConfigurationManager).Add
item.SetConfiguration(GetParentManager)
End Sub
Public Sub Clear() Implements ICollection(Of ConfigurationManager).Clear
For Each item As ConfigurationManager In myList
item.SetConfiguration(Nothing)
Next
myList.Clear()
End Sub
Public Sub CopyTo(array() As ConfigurationManager, arrayIndex As Integer) Implements ICollection(Of ConfigurationManager).CopyTo
myList.CopyTo(array, arrayIndex)
End Sub
Public Function IndexOf(item As ConfigurationManager) As Integer Implements IList(Of ConfigurationManager).IndexOf
Return myList.IndexOf(item)
End Function
Public Function Contains(item As ConfigurationManager) As Boolean Implements ICollection(Of ConfigurationManager).Contains
Return myList.Contains(item)
End Function
Public Function Remove(item As ConfigurationManager) As Boolean Implements ICollection(Of ConfigurationManager).Remove
item.SetConfiguration(Nothing)
Return myList.Remove(item)
End Function
Public Function GetEnumerator() As IEnumerator(Of ConfigurationManager) Implements IEnumerable(Of ConfigurationManager).GetEnumerator
Return IEnumerable_GetEnumerator()
End Function
Private Function IEnumerable_GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator
Return myList.GetEnumerator
End Function
End Class

View File

@@ -0,0 +1,139 @@
using System.IO;
using Newtonsoft.Json;
using Pilz.GeneralEventArgs;
namespace Pilz.Configuration
{
public static class ConfigurationSerializer
{
public static event GettingJsonSerializerEventHandler GettingJsonSerializer;
public delegate void GettingJsonSerializerEventHandler(object instance, GetValueEventArgs<JsonSerializer> e);
private static JsonSerializer GetJsonSerializer(SimpleConfiguration instance)
{
var args = new GetValueEventArgs<JsonSerializer>(JsonSerializer.CreateDefault());
GettingJsonSerializer?.Invoke(instance, args);
return args.Value;
}
/// <summary>
/// Writes the given instance to a string and return it.
/// </summary>
/// <param name="instance">The configuration instance that should be serialized.</param>
/// <returns>The content of the configuration instance as string.</returns>
public static string WriteToString(SimpleConfiguration instance)
{
var tw = new StringWriter();
GetJsonSerializer(instance).Serialize(tw, instance);
string txt = tw.ToString();
tw.Close();
return txt;
}
/// <summary>
/// Write the given instance to a given stream.
/// </summary>
/// <param name="instance">The configuration instance that should be serialized.</param>
/// <param name="stream">The stream where the content should be written to.</param>
public static void WriteToStream(SimpleConfiguration instance, Stream stream)
{
var sr = new StreamWriter(stream);
sr.Write(WriteToString(instance));
}
/// <summary>
/// Writes the given instance to the given filePath as text file.
/// </summary>
/// <param name="instance">The configuration instance that should be serialized.</param>
/// <param name="filePath">The file path where the content should be written to. The file will be created or overwritten.</param>
public static void WriteToFile(SimpleConfiguration instance, string filePath)
{
var fs = new FileStream(filePath, FileMode.Create, FileAccess.ReadWrite);
WriteToStream(instance, fs);
fs.Close();
}
/// <summary>
/// Reads a configuratin from the given string and returns an instance of it.
/// </summary>
/// <typeparam name="T">The type of the configuration class to instance.</typeparam>
/// <param name="content">The content of the configuration as string.</param>
/// <returns></returns>
public static T ReadFromString<T>(string content) where T : SimpleConfiguration
{
var sr = new StringReader(content);
T instance = (T)GetJsonSerializer(null).Deserialize(sr, typeof(T));
sr.Close();
return instance;
}
/// <summary>
/// Read a configuration from the given string and put them to the given instance.
/// </summary>
/// <param name="instance">The instance to populate with the configuration.</param>
/// <param name="content">The content of the configuration as string.</param>
public static void ReadFromString(SimpleConfiguration instance, string content)
{
var sr = new StringReader(content);
GetJsonSerializer(null).Populate(sr, content);
sr.Close();
}
/// <summary>
/// Reads a configuratin from the given string and returns an instance of it.
/// </summary>
/// <typeparam name="T">The type of the configuration class to instance.</typeparam>
/// <param name="stream">The stream with the content of the configuration.</param>
/// <returns></returns>
public static T ReadFromStream<T>(Stream stream) where T : SimpleConfiguration
{
return ReadFromString<T>(GetContentOfStream(stream));
}
/// <summary>
/// Read a configuration from the given string and put them to the given instance.
/// </summary>
/// <param name="instance">The instance to populate with the configuration.</param>
/// <param name="stream">The stream with the content of the configuration.</param>
public static void ReadFromStream(SimpleConfiguration instance, Stream stream)
{
ReadFromString(instance, GetContentOfStream(stream));
}
/// <summary>
/// Reads a configuratin from the given string and returns an instance of it.
/// </summary>
/// <typeparam name="T">The type of the configuration class to instance.</typeparam>
/// <param name="filePath">The path to the file with the content of the configuration.</param>
/// <returns></returns>
public static T ReadFromFile<T>(string filePath) where T : SimpleConfiguration
{
return ReadFromString<T>(GetContentOfFile(filePath));
}
/// <summary>
/// Read a configuration from the given string and put them to the given instance.
/// </summary>
/// <param name="instance">The instance to populate with the configuration.</param>
/// <param name="filePath">The path to the file with the content of the configuration.</param>
public static void ReadFromFile(SimpleConfiguration instance, string filePath)
{
ReadFromString(instance, GetContentOfFile(filePath));
}
private static string GetContentOfStream(Stream stream)
{
var sr = new StreamReader(stream);
return sr.ReadToEnd();
}
private static string GetContentOfFile(string filePath)
{
var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read);
string content = GetContentOfStream(fs);
fs.Close();
return content;
}
}
}

View File

@@ -1,123 +0,0 @@
Imports System.IO
Imports Newtonsoft.Json
Imports Pilz.GeneralEventArgs
Public Module ConfigurationSerializer
Public Event GettingJsonSerializer(instance As Object, e As GetValueEventArgs(Of JsonSerializer))
Private Function GetJsonSerializer(instance As SimpleConfiguration) As JsonSerializer
Dim args As New GetValueEventArgs(Of JsonSerializer)(JsonSerializer.CreateDefault)
RaiseEvent GettingJsonSerializer(instance, args)
Return args.Value
End Function
''' <summary>
''' Writes the given instance to a string and return it.
''' </summary>
''' <param name="instance">The configuration instance that should be serialized.</param>
''' <returns>The content of the configuration instance as string.</returns>
Public Function WriteToString(instance As SimpleConfiguration) As String
Dim tw As New StringWriter
GetJsonSerializer(instance).Serialize(tw, instance)
Dim txt = tw.ToString
tw.Close()
Return txt
End Function
''' <summary>
''' Write the given instance to a given stream.
''' </summary>
''' <param name="instance">The configuration instance that should be serialized.</param>
''' <param name="stream">The stream where the content should be written to.</param>
Public Sub WriteToStream(instance As SimpleConfiguration, stream As Stream)
Dim sr As New StreamWriter(stream)
sr.Write(WriteToString(instance))
End Sub
''' <summary>
''' Writes the given instance to the given filePath as text file.
''' </summary>
''' <param name="instance">The configuration instance that should be serialized.</param>
''' <param name="filePath">The file path where the content should be written to. The file will be created or overwritten.</param>
Public Sub WriteToFile(instance As SimpleConfiguration, filePath As String)
Dim fs As New FileStream(filePath, FileMode.Create, FileAccess.ReadWrite)
WriteToStream(instance, fs)
fs.Close()
End Sub
''' <summary>
''' Reads a configuratin from the given string and returns an instance of it.
''' </summary>
''' <typeparam name="T">The type of the configuration class to instance.</typeparam>
''' <param name="content">The content of the configuration as string.</param>
''' <returns></returns>
Public Function ReadFromString(Of T As SimpleConfiguration)(content As String) As T
Dim sr As New StringReader(content)
Dim instance As T = GetJsonSerializer(Nothing).Deserialize(sr, GetType(T))
sr.Close()
Return instance
End Function
''' <summary>
''' Read a configuration from the given string and put them to the given instance.
''' </summary>
''' <param name="instance">The instance to populate with the configuration.</param>
''' <param name="content">The content of the configuration as string.</param>
Public Sub ReadFromString(instance As SimpleConfiguration, content As String)
Dim sr As New StringReader(content)
GetJsonSerializer(Nothing).Populate(sr, content)
sr.Close()
End Sub
''' <summary>
''' Reads a configuratin from the given string and returns an instance of it.
''' </summary>
''' <typeparam name="T">The type of the configuration class to instance.</typeparam>
''' <param name="stream">The stream with the content of the configuration.</param>
''' <returns></returns>
Public Function ReadFromStream(Of T As SimpleConfiguration)(stream As Stream) As T
Return ReadFromString(Of T)(GetContentOfStream(stream))
End Function
''' <summary>
''' Read a configuration from the given string and put them to the given instance.
''' </summary>
''' <param name="instance">The instance to populate with the configuration.</param>
''' <param name="stream">The stream with the content of the configuration.</param>
Public Sub ReadFromStream(instance As SimpleConfiguration, stream As Stream)
ReadFromString(instance, GetContentOfStream(stream))
End Sub
''' <summary>
''' Reads a configuratin from the given string and returns an instance of it.
''' </summary>
''' <typeparam name="T">The type of the configuration class to instance.</typeparam>
''' <param name="filePath">The path to the file with the content of the configuration.</param>
''' <returns></returns>
Public Function ReadFromFile(Of T As SimpleConfiguration)(filePath As String) As T
Return ReadFromString(Of T)(GetContentOfFile(filePath))
End Function
''' <summary>
''' Read a configuration from the given string and put them to the given instance.
''' </summary>
''' <param name="instance">The instance to populate with the configuration.</param>
''' <param name="filePath">The path to the file with the content of the configuration.</param>
Public Sub ReadFromFile(instance As SimpleConfiguration, filePath As String)
ReadFromString(instance, GetContentOfFile(filePath))
End Sub
Private Function GetContentOfStream(stream As Stream) As String
Dim sr As New StreamReader(stream)
Return sr.ReadToEnd
End Function
Private Function GetContentOfFile(filePath As String) As String
Dim fs As New FileStream(filePath, FileMode.Open, FileAccess.Read)
Dim content = GetContentOfStream(fs)
fs.Close()
Return content
End Function
End Module

View File

@@ -0,0 +1,7 @@
namespace Pilz.Configuration
{
public interface IChildSettings
{
void Reset();
}
}

View File

@@ -1,5 +0,0 @@
Public Interface IChildSettings
Sub Reset()
End Interface

View File

@@ -0,0 +1,11 @@
using System.Collections.Generic;
namespace Pilz.Configuration
{
public interface ISettings
{
IReadOnlyCollection<IChildSettings> Childs { get; }
T Get<T>() where T : IChildSettings, ISettingsIdentifier;
void Reset();
}
}

View File

@@ -1,9 +0,0 @@
Public Interface ISettings
ReadOnly Property Settings As IReadOnlyCollection(Of IChildSettings)
Function [Get](Of T As IChildSettings)() As T
Sub Reset()
Sub Initialize(providers As List(Of ISettingsProvider))
End Interface

View File

@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Pilz.Configuration
{
public interface ISettingsIdentifier
{
static abstract string Identifier { get; }
}
}

View File

@@ -0,0 +1,11 @@
namespace Pilz.Configuration
{
public interface ISettingsManager
{
ISettings Instance { get; }
void Save();
void Load();
void Reset();
}
}

View File

@@ -1,6 +0,0 @@
Public Interface ISettingsManager
ReadOnly Property Instance As ISettings
Sub Save()
Sub Load()
Sub Reset()
End Interface

View File

@@ -1,7 +0,0 @@
Public Interface ISettingsProvider
Function GetSettingsIdentifiers() As List(Of String)
Function CreateInstance(identifier As String) As IChildSettings
End Interface

View File

@@ -1,31 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFrameworks>netstandard2.0;net8.0</TargetFrameworks> <TargetFrameworks>net8.0</TargetFrameworks>
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn> <NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022,1591</NoWarn>
<DocumentationFile>Pilz.Configuration.xml</DocumentationFile> <DocumentationFile>Pilz.Configuration.xml</DocumentationFile>
<DefineTrace>true</DefineTrace> <DefaultItemExcludes>$(DefaultItemExcludes);$(ProjectDir)**\*.vb</DefaultItemExcludes>
<LangVersion>latest</LangVersion>
<DefineConstants>TRACE</DefineConstants>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DefineDebug>true</DefineDebug> <DefineConstants>DEBUG</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DefineDebug>false</DefineDebug>
</PropertyGroup>
<PropertyGroup>
<OptionExplicit>On</OptionExplicit>
</PropertyGroup>
<PropertyGroup>
<OptionCompare>Binary</OptionCompare>
</PropertyGroup>
<PropertyGroup>
<OptionStrict>Off</OptionStrict>
</PropertyGroup>
<PropertyGroup>
<OptionInfer>On</OptionInfer>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
<PropertyGroup> <PropertyGroup>
<GeneratePackageOnBuild>True</GeneratePackageOnBuild> <GeneratePackageOnBuild>True</GeneratePackageOnBuild>
<Version>3.0.</Version> <Version>3.1.0</Version>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="System.Data.DataSetExtensions" Version="4.5.0" /> <PackageReference Include="System.Data.DataSetExtensions" Version="4.5.0" />

View File

@@ -0,0 +1,36 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
namespace Pilz.Configuration
{
public class Settings : ISettings
{
[JsonProperty(nameof(Settings))]
protected readonly Dictionary<string, IChildSettings> mySettings = [];
[JsonIgnore]
public IReadOnlyCollection<IChildSettings> Childs => mySettings.Values;
public T Get<T>() where T : IChildSettings, ISettingsIdentifier
{
if (mySettings.TryGetValue(T.Identifier, out IChildSettings valueExisting) && valueExisting is T settingsExisting)
return settingsExisting;
if (Activator.CreateInstance<T>() is T settingsNew)
{
mySettings.Add(T.Identifier, settingsNew);
return settingsNew;
}
return default;
}
public void Reset()
{
foreach (var s in mySettings.Values)
s.Reset();
}
}
}

View File

@@ -1,40 +0,0 @@
Imports System.Runtime
Imports Newtonsoft.Json
Public Class Settings
Implements ISettings
<JsonProperty(NameOf(Settings))>
Protected ReadOnly mySettings As New Dictionary(Of String, IChildSettings)
<JsonIgnore>
Public ReadOnly Property Settings As IReadOnlyCollection(Of IChildSettings) Implements ISettings.Settings
Get
Return mySettings.Values
End Get
End Property
Public Function [Get](Of T As IChildSettings)() As T Implements ISettings.Get
Return mySettings.Values.OfType(Of T).FirstOrDefault
End Function
Public Sub Reset() Implements ISettings.Reset
For Each s In mySettings.Values
s.Reset()
Next
End Sub
Public Sub Initialize(providers As List(Of ISettingsProvider)) Implements ISettings.Initialize
For Each provider In providers
For Each identifier In provider.GetSettingsIdentifiers
If Not mySettings.ContainsKey(identifier) Then
Dim s = provider.CreateInstance(identifier)
s.Reset()
mySettings.Add(identifier, s)
End If
Next
Next
End Sub
End Class

View File

@@ -0,0 +1,126 @@
using System;
using System.Collections.Generic;
using System.IO;
using Newtonsoft.Json;
namespace Pilz.Configuration
{
public class SettingsManager : ISettingsManager
{
public event EventHandler AutoSavingSettings;
public event EventHandler SavingSettings;
public event EventHandler SavedSettings;
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
};
}
}
}

View File

@@ -1,122 +0,0 @@
Imports System.IO
Imports Newtonsoft.Json
Public Class SettingsManager
Implements ISettingsManager
Public Shared Event InitializingManager As EventHandler
Public Event AutoSavingSettings As EventHandler
Public Event SavingSettings As EventHandler
Public Event SavedSettings As EventHandler
Protected ReadOnly settingsProvider As New List(Of ISettingsProvider)
Protected defaultInstance As ISettings = Nothing
Protected enableAutoSave As Boolean = False
Protected addedHandler As Boolean = False
Public Property ConfigFilePath As String
Public ReadOnly Property Instance As ISettings Implements ISettingsManager.Instance
Get
If defaultInstance Is Nothing Then
Load()
End If
Return defaultInstance
End Get
End Property
Public Property AutoSaveOnExit As Boolean
Get
Return enableAutoSave
End Get
Set
If enableAutoSave <> Value Then
enableAutoSave = Value
Select Case enableAutoSave
Case True
If Not addedHandler Then
AddAutoSaveHandler()
End If
Case False
If addedHandler Then
RemoveAutoSaveHandler()
End If
End Select
End If
End Set
End Property
Public Sub New()
RaiseEvent InitializingManager(Me, EventArgs.Empty)
End Sub
Public Sub New(fileName As String, autoSaveOnExit As Boolean)
Me.New
ConfigFilePath = fileName
Me.AutoSaveOnExit = autoSaveOnExit
End Sub
Public Sub RegisterProvider(provider As ISettingsProvider)
settingsProvider.Add(provider)
End Sub
Protected Sub AddAutoSaveHandler()
AddHandler AppDomain.CurrentDomain.ProcessExit, AddressOf AutoSaveSettingsOnExit
addedHandler = True
End Sub
Protected Sub RemoveAutoSaveHandler()
RemoveHandler AppDomain.CurrentDomain.ProcessExit, AddressOf AutoSaveSettingsOnExit
addedHandler = False
End Sub
Private Sub AutoSaveSettingsOnExit(sender As Object, e As EventArgs)
RaiseEvent AutoSavingSettings(Me, New EventArgs)
Save()
End Sub
Public Sub Save() Implements ISettingsManager.Save
If Not String.IsNullOrEmpty(ConfigFilePath) AndAlso defaultInstance IsNot Nothing Then
SaveInternal()
End If
End Sub
Public Sub Load() Implements ISettingsManager.Load
If Not String.IsNullOrEmpty(ConfigFilePath) AndAlso File.Exists(ConfigFilePath) Then
LoadInternal()
Else
CreateNewInstance()
End If
End Sub
Public Sub Reset() Implements ISettingsManager.Reset
Instance.Reset()
End Sub
Protected Overridable Sub CreateNewInstance()
defaultInstance = New Settings
defaultInstance.Initialize(settingsProvider)
defaultInstance.Reset()
End Sub
Protected Overridable Sub LoadInternal()
defaultInstance = JsonConvert.DeserializeObject(Of Settings)(File.ReadAllText(ConfigFilePath), CreateJsonSerializerSettings)
defaultInstance.Initialize(settingsProvider)
End Sub
Protected Overridable Sub SaveInternal()
RaiseEvent SavingSettings(Me, EventArgs.Empty)
File.WriteAllText(ConfigFilePath, JsonConvert.SerializeObject(defaultInstance, CreateJsonSerializerSettings))
RaiseEvent SavedSettings(Me, EventArgs.Empty)
End Sub
Protected Overridable Function CreateJsonSerializerSettings() As JsonSerializerSettings
Return New JsonSerializerSettings With {
.Formatting = Formatting.Indented,
.TypeNameHandling = TypeNameHandling.Auto
}
End Function
End Class

View File

@@ -0,0 +1,110 @@
using System.IO;
using Newtonsoft.Json;
using Pilz.GeneralEventArgs;
namespace Pilz.Configuration
{
public class SimpleConfiguration
{
[JsonIgnore]
public readonly ConfigurationManagerList Managers = new ConfigurationManagerList();
public SimpleConfiguration()
{
Managers.GettingParentManager += Managers_GettingParentManager;
}
private void Managers_GettingParentManager(object sender, GetValueEventArgs<SimpleConfiguration> e)
{
if (ReferenceEquals(sender, Managers))
e.Value = this;
}
/// <summary>
/// Writes this instance to a string and return it.
/// </summary>
/// <returns>The content of the configuration instance as string.</returns>
public string WriteToString()
{
return ConfigurationSerializer.WriteToString(this);
}
/// <summary>
/// Write this instance to a given stream.
/// </summary>
/// <param name="stream">The stream where the content should be written to.</param>
public void WriteToStream(Stream stream)
{
ConfigurationSerializer.WriteToStream(this, stream);
}
/// <summary>
/// Writes this instance to the given filePath as text file.
/// </summary>
/// <param name="filePath">The file path where the content should be written to. The file will be created or overwritten.</param>
public void WriteToFile(string filePath)
{
ConfigurationSerializer.WriteToFile(this, filePath);
}
/// <summary>
/// Reads a configuratin from the given string and returns an instance of it.
/// </summary>
/// <typeparam name="T">The type of the configuration class to instance.</typeparam>
/// <param name="content">The content of the configuration as string.</param>
/// <returns></returns>
public static T ReadFromString<T>(string content) where T : SimpleConfiguration
{
return ConfigurationSerializer.ReadFromString<T>(content);
}
/// <summary>
/// Read a configuration from the given string and put them to this instance.
/// </summary>
/// <param name="content">The content of the configuration as string.</param>
public void ReadFromString(string content)
{
ConfigurationSerializer.ReadFromString(this, content);
}
/// <summary>
/// Reads a configuratin from the given string and returns an instance of it.
/// </summary>
/// <typeparam name="T">The type of the configuration class to instance.</typeparam>
/// <param name="stream">The stream with the content of the configuration.</param>
/// <returns></returns>
public static T ReadFromStream<T>(Stream stream) where T : SimpleConfiguration
{
return ConfigurationSerializer.ReadFromStream<T>(stream);
}
/// <summary>
/// Read a configuration from the given string and put them to this instance.
/// </summary>
/// <param name="stream">The stream with the content of the configuration.</param>
public void ReadFromStream(Stream stream)
{
ConfigurationSerializer.ReadFromStream(this, stream);
}
/// <summary>
/// Reads a configuratin from the given string and returns an instance of it.
/// </summary>
/// <typeparam name="T">The type of the configuration class to instance.</typeparam>
/// <param name="filePath">The path to the file with the content of the configuration.</param>
/// <returns></returns>
public static T ReadFromFile<T>(string filePath) where T : SimpleConfiguration
{
return ConfigurationSerializer.ReadFromFile<T>(filePath);
}
/// <summary>
/// Read a configuration from the given string and put them to this instance.
/// </summary>
/// <param name="filePath">The path to the file with the content of the configuration.</param>
public void ReadFromFile(string filePath)
{
ConfigurationSerializer.ReadFromFile(this, filePath);
}
}
}

View File

@@ -1,99 +0,0 @@
Imports System.IO
Imports Newtonsoft.Json
Imports Pilz.Configuration
Imports Pilz.GeneralEventArgs
Public Class SimpleConfiguration
<JsonIgnore>
Public ReadOnly Managers As New ConfigurationManagerList
Public Sub New()
AddHandler Managers.GettingParentManager, AddressOf Managers_GettingParentManager
End Sub
Private Sub Managers_GettingParentManager(sender As Object, e As GetValueEventArgs(Of SimpleConfiguration))
If sender Is Managers Then
e.Value = Me
End If
End Sub
''' <summary>
''' Writes this instance to a string and return it.
''' </summary>
''' <returns>The content of the configuration instance as string.</returns>
Public Function WriteToString() As String
Return ConfigurationSerializer.WriteToString(Me)
End Function
''' <summary>
''' Write this instance to a given stream.
''' </summary>
''' <param name="stream">The stream where the content should be written to.</param>
Public Sub WriteToStream(stream As Stream)
ConfigurationSerializer.WriteToStream(Me, stream)
End Sub
''' <summary>
''' Writes this instance to the given filePath as text file.
''' </summary>
''' <param name="filePath">The file path where the content should be written to. The file will be created or overwritten.</param>
Public Sub WriteToFile(filePath As String)
ConfigurationSerializer.WriteToFile(Me, filePath)
End Sub
''' <summary>
''' Reads a configuratin from the given string and returns an instance of it.
''' </summary>
''' <typeparam name="T">The type of the configuration class to instance.</typeparam>
''' <param name="content">The content of the configuration as string.</param>
''' <returns></returns>
Public Shared Function ReadFromString(Of T As SimpleConfiguration)(content As String) As T
Return ConfigurationSerializer.ReadFromString(Of T)(content)
End Function
''' <summary>
''' Read a configuration from the given string and put them to this instance.
''' </summary>
''' <param name="content">The content of the configuration as string.</param>
Public Sub ReadFromString(content As String)
ConfigurationSerializer.ReadFromString(Me, content)
End Sub
''' <summary>
''' Reads a configuratin from the given string and returns an instance of it.
''' </summary>
''' <typeparam name="T">The type of the configuration class to instance.</typeparam>
''' <param name="stream">The stream with the content of the configuration.</param>
''' <returns></returns>
Public Shared Function ReadFromStream(Of T As SimpleConfiguration)(stream As Stream) As T
Return ConfigurationSerializer.ReadFromStream(Of T)(stream)
End Function
''' <summary>
''' Read a configuration from the given string and put them to this instance.
''' </summary>
''' <param name="stream">The stream with the content of the configuration.</param>
Public Sub ReadFromStream(stream As Stream)
ConfigurationSerializer.ReadFromStream(Me, stream)
End Sub
''' <summary>
''' Reads a configuratin from the given string and returns an instance of it.
''' </summary>
''' <typeparam name="T">The type of the configuration class to instance.</typeparam>
''' <param name="filePath">The path to the file with the content of the configuration.</param>
''' <returns></returns>
Public Shared Function ReadFromFile(Of T As SimpleConfiguration)(filePath As String) As T
Return ConfigurationSerializer.ReadFromFile(Of T)(filePath)
End Function
''' <summary>
''' Read a configuration from the given string and put them to this instance.
''' </summary>
''' <param name="filePath">The path to the file with the content of the configuration.</param>
Public Sub ReadFromFile(filePath As String)
ConfigurationSerializer.ReadFromFile(Me, filePath)
End Sub
End Class

View File

@@ -17,7 +17,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Pilz.IO", "Pilz.IO\Pilz.IO.
EndProject EndProject
Project("{778DAE3C-4631-46EA-AA77-85C1314464D9}") = "Pilz.Win32", "Pilz.Win32\Pilz.Win32.vbproj", "{0BE0428D-AC97-4812-ADFC-6D7D00AEE497}" Project("{778DAE3C-4631-46EA-AA77-85C1314464D9}") = "Pilz.Win32", "Pilz.Win32\Pilz.Win32.vbproj", "{0BE0428D-AC97-4812-ADFC-6D7D00AEE497}"
EndProject EndProject
Project("{778DAE3C-4631-46EA-AA77-85C1314464D9}") = "Pilz.Configuration", "Pilz.Configuration\Pilz.Configuration.vbproj", "{A56C6153-C61F-4B10-BE06-35EB0448CFDC}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Pilz.Configuration", "Pilz.Configuration\Pilz.Configuration.csproj", "{1748E038-0A47-04E1-3C5E-FF9566DFFB7C}"
EndProject EndProject
Project("{778DAE3C-4631-46EA-AA77-85C1314464D9}") = "Pilz.Reflection.PluginSystem", "Pilz.Reflection.PluginSystem\Pilz.Reflection.PluginSystem.vbproj", "{F7975470-4CA3-4FAB-BB6A-A3AF3978ABB7}" Project("{778DAE3C-4631-46EA-AA77-85C1314464D9}") = "Pilz.Reflection.PluginSystem", "Pilz.Reflection.PluginSystem\Pilz.Reflection.PluginSystem.vbproj", "{F7975470-4CA3-4FAB-BB6A-A3AF3978ABB7}"
EndProject EndProject
@@ -107,14 +107,14 @@ Global
{0BE0428D-AC97-4812-ADFC-6D7D00AEE497}.Release|Any CPU.Build.0 = Release|Any CPU {0BE0428D-AC97-4812-ADFC-6D7D00AEE497}.Release|Any CPU.Build.0 = Release|Any CPU
{0BE0428D-AC97-4812-ADFC-6D7D00AEE497}.Release|x86.ActiveCfg = Release|Any CPU {0BE0428D-AC97-4812-ADFC-6D7D00AEE497}.Release|x86.ActiveCfg = Release|Any CPU
{0BE0428D-AC97-4812-ADFC-6D7D00AEE497}.Release|x86.Build.0 = Release|Any CPU {0BE0428D-AC97-4812-ADFC-6D7D00AEE497}.Release|x86.Build.0 = Release|Any CPU
{A56C6153-C61F-4B10-BE06-35EB0448CFDC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {1748E038-0A47-04E1-3C5E-FF9566DFFB7C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A56C6153-C61F-4B10-BE06-35EB0448CFDC}.Debug|Any CPU.Build.0 = Debug|Any CPU {1748E038-0A47-04E1-3C5E-FF9566DFFB7C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A56C6153-C61F-4B10-BE06-35EB0448CFDC}.Debug|x86.ActiveCfg = Debug|Any CPU {1748E038-0A47-04E1-3C5E-FF9566DFFB7C}.Debug|x86.ActiveCfg = Debug|Any CPU
{A56C6153-C61F-4B10-BE06-35EB0448CFDC}.Debug|x86.Build.0 = Debug|Any CPU {1748E038-0A47-04E1-3C5E-FF9566DFFB7C}.Debug|x86.Build.0 = Debug|Any CPU
{A56C6153-C61F-4B10-BE06-35EB0448CFDC}.Release|Any CPU.ActiveCfg = Release|Any CPU {1748E038-0A47-04E1-3C5E-FF9566DFFB7C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A56C6153-C61F-4B10-BE06-35EB0448CFDC}.Release|Any CPU.Build.0 = Release|Any CPU {1748E038-0A47-04E1-3C5E-FF9566DFFB7C}.Release|Any CPU.Build.0 = Release|Any CPU
{A56C6153-C61F-4B10-BE06-35EB0448CFDC}.Release|x86.ActiveCfg = Release|Any CPU {1748E038-0A47-04E1-3C5E-FF9566DFFB7C}.Release|x86.ActiveCfg = Release|Any CPU
{A56C6153-C61F-4B10-BE06-35EB0448CFDC}.Release|x86.Build.0 = Release|Any CPU {1748E038-0A47-04E1-3C5E-FF9566DFFB7C}.Release|x86.Build.0 = Release|Any CPU
{F7975470-4CA3-4FAB-BB6A-A3AF3978ABB7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {F7975470-4CA3-4FAB-BB6A-A3AF3978ABB7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F7975470-4CA3-4FAB-BB6A-A3AF3978ABB7}.Debug|Any CPU.Build.0 = Debug|Any CPU {F7975470-4CA3-4FAB-BB6A-A3AF3978ABB7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F7975470-4CA3-4FAB-BB6A-A3AF3978ABB7}.Debug|x86.ActiveCfg = Debug|Any CPU {F7975470-4CA3-4FAB-BB6A-A3AF3978ABB7}.Debug|x86.ActiveCfg = Debug|Any CPU