diff --git a/Pilz.Configuration/IChildSettings.vb b/Pilz.Configuration/IChildSettings.vb new file mode 100644 index 0000000..9f282c9 --- /dev/null +++ b/Pilz.Configuration/IChildSettings.vb @@ -0,0 +1,5 @@ +Public Interface IChildSettings + + Sub Reset() + +End Interface diff --git a/Pilz.Configuration/ISettings.vb b/Pilz.Configuration/ISettings.vb new file mode 100644 index 0000000..e7cddd2 --- /dev/null +++ b/Pilz.Configuration/ISettings.vb @@ -0,0 +1,9 @@ +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 diff --git a/Pilz.Configuration/ISettingsProvider.vb b/Pilz.Configuration/ISettingsProvider.vb new file mode 100644 index 0000000..e43e9b5 --- /dev/null +++ b/Pilz.Configuration/ISettingsProvider.vb @@ -0,0 +1,7 @@ +Public Interface ISettingsProvider + + Function GetSettingsIdentifiers() As List(Of String) + + Function CreateInstance(identifier As String) + +End Interface diff --git a/Pilz.Configuration/Pilz.Configuration.vbproj b/Pilz.Configuration/Pilz.Configuration.vbproj index 50265dd..ff9985e 100644 --- a/Pilz.Configuration/Pilz.Configuration.vbproj +++ b/Pilz.Configuration/Pilz.Configuration.vbproj @@ -25,7 +25,7 @@ True - 2.0.0 + 3.0.0 diff --git a/Pilz.Configuration/Settings.vb b/Pilz.Configuration/Settings.vb new file mode 100644 index 0000000..50aba31 --- /dev/null +++ b/Pilz.Configuration/Settings.vb @@ -0,0 +1,40 @@ +Imports System.Runtime + +Imports Newtonsoft.Json + +Public Class Settings + Implements ISettings + + + Private ReadOnly mySettings As New Dictionary(Of String, IChildSettings) + + + 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 diff --git a/Pilz.Configuration/SettingsBase.vb b/Pilz.Configuration/SettingsBase.vb deleted file mode 100644 index 2f2ee29..0000000 --- a/Pilz.Configuration/SettingsBase.vb +++ /dev/null @@ -1,20 +0,0 @@ -Imports Newtonsoft.Json - -Public MustInherit Class SettingsBase - - Public Sub New() - ResetValues() - End Sub - - - Friend _settingsManager As ISettingsManager - - Public ReadOnly Property SettingsManager As ISettingsManager - Get - Return _settingsManager - End Get - End Property - - Public MustOverride Sub ResetValues() - -End Class diff --git a/Pilz.Configuration/SettingsManager.vb b/Pilz.Configuration/SettingsManager.vb index b32ea99..5aa2b49 100644 --- a/Pilz.Configuration/SettingsManager.vb +++ b/Pilz.Configuration/SettingsManager.vb @@ -1,20 +1,32 @@ Imports System.IO -Imports System.Reflection -Imports Newtonsoft.Json.Linq -Public NotInheritable Class SettingsManager(Of T As SettingsBase) +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 - Private defaultInstance As T = Nothing + Private ReadOnly settingsProvider As New List(Of ISettingsProvider) + Private defaultInstance As ISettings = Nothing Private enableAutoSave As Boolean = False Private addedHandler As Boolean = False Public Property ConfigFilePath As String Implements ISettingsManager.ConfigFilePath + Public ReadOnly Property Instance As IChildSettings + Get + If defaultInstance Is Nothing Then + Load() + End If + Return defaultInstance + End Get + End Property + Public Property AutoSaveOnExit As Boolean Get Return enableAutoSave @@ -40,25 +52,18 @@ Public NotInheritable Class SettingsManager(Of T As SettingsBase) AddHandler AppDomain.CurrentDomain.ProcessExit, AddressOf AutoSaveSettingsOnExit addedHandler = True End Sub + Private Sub RemoveAutoSaveHandler() RemoveHandler AppDomain.CurrentDomain.ProcessExit, AddressOf AutoSaveSettingsOnExit addedHandler = False End Sub - Public ReadOnly Property Instance As T - Get - If defaultInstance Is Nothing Then - Load() - End If - Return defaultInstance - End Get - End Property - Public Sub New() - ConfigFilePath = "" - AutoSaveOnExit = False + 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 @@ -70,50 +75,44 @@ Public NotInheritable Class SettingsManager(Of T As SettingsBase) Public Sub Save() Implements ISettingsManager.Save If Not String.IsNullOrEmpty(ConfigFilePath) AndAlso defaultInstance IsNot Nothing Then - SavePrivate() + SaveInternal() End If End Sub Public Sub Load() Implements ISettingsManager.Load If Not String.IsNullOrEmpty(ConfigFilePath) AndAlso File.Exists(ConfigFilePath) Then - LoadPrivate() + LoadInternal() Else CreateNewInstance() End If - - If defaultInstance IsNot Nothing Then - defaultInstance._settingsManager = Me - End If End Sub Public Sub Reset() Implements ISettingsManager.Reset - Instance.ResetValues() + Instance.Reset() End Sub - Private Sub CreateNewInstance() - Dim ctor As ConstructorInfo = GetType(T).GetConstructor({}) - If ctor IsNot Nothing Then - defaultInstance = ctor.Invoke({}) - - defaultInstance.ResetValues() - Else - Throw New Exception("The base type has no constructor with no parameters.") - End If + Protected Overridable Sub CreateNewInstance() + defaultInstance = New Settings + defaultInstance.Initialize(settingsProvider) + defaultInstance.Reset() End Sub - Private Sub LoadPrivate() - defaultInstance = JObject.Parse(File.ReadAllText(ConfigFilePath)).ToObject(Of T) + Protected Overridable Sub LoadInternal() + defaultInstance = JsonConvert.DeserializeObject(Of Settings)(File.ReadAllText(ConfigFilePath), CreateJsonSerializerSettings) + defaultInstance.Initialize(settingsProvider) End Sub - Private Sub SavePrivate() - RaiseEvent SavingSettings(Me, New EventArgs) - - Dim obj As JObject = JObject.FromObject(defaultInstance) - If obj IsNot Nothing Then - File.WriteAllText(ConfigFilePath, obj.ToString) - End If - - RaiseEvent SavedSettings(Me, New EventArgs) + 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