166 lines
5.7 KiB
VB.net
166 lines
5.7 KiB
VB.net
Imports System.IO
|
|
Imports System.Xml.Serialization
|
|
Imports DigitalData.Modules.Logging
|
|
Imports DigitalData.Modules.Filesystem
|
|
Imports System.Xml
|
|
|
|
Public Class ConfigManager(Of T)
|
|
Private Const USER_CONFIG_NAME As String = "UserConfig.xml"
|
|
Private Const COMPUTER_CONFIG_NAME As String = "ComputerConfig.xml"
|
|
|
|
Private ReadOnly _LogConfig As LogConfig
|
|
Private ReadOnly _Logger As Logger
|
|
Private ReadOnly _File As Filesystem.File
|
|
Private ReadOnly _UserPath As String
|
|
Private ReadOnly _ComputerPath As String
|
|
Private _CurrentDataPath As String
|
|
|
|
''' <summary>
|
|
''' The blueprint class from which the default config is created
|
|
''' </summary>
|
|
Private ReadOnly _Blueprint As T
|
|
Private ReadOnly _Serializer As XmlSerializer
|
|
|
|
Public ReadOnly Property Config As T
|
|
|
|
|
|
''' <summary>
|
|
''' Creates a new instance of the ConfigManager
|
|
''' </summary>
|
|
''' <example>
|
|
''' Public Class Config
|
|
''' Public Property StringEntry As String = "TEST"
|
|
''' Public Property BoolEntry As Boolean = True
|
|
''' Public Property IntEntry As Integer = 123
|
|
''' End Class
|
|
'''
|
|
''' Dim oConfigManager = New ConfigManager(Of Config)(_LogConfig, Application.UserAppDataPath, Application.CommonAppDataPath)
|
|
''' </example>
|
|
''' <param name="LogConfig">LogConfig instance</param>
|
|
''' <param name="UserConfigPath">The first path to check for a config file, eg. AppData</param>
|
|
''' <param name="ComputerConfigPath">The second path to check for a config file, eg. ProgramData</param>
|
|
Public Sub New(LogConfig As LogConfig, UserConfigPath As String, ComputerConfigPath As String)
|
|
_LogConfig = LogConfig
|
|
_Logger = LogConfig.GetLogger()
|
|
_File = New Filesystem.File(_LogConfig)
|
|
|
|
_UserPath = Path.Combine(UserConfigPath, USER_CONFIG_NAME)
|
|
_ComputerPath = Path.Combine(ComputerConfigPath, COMPUTER_CONFIG_NAME)
|
|
|
|
_Blueprint = Activator.CreateInstance(Of T)
|
|
_Serializer = New XmlSerializer(_Blueprint.GetType)
|
|
|
|
If Not Directory.Exists(UserConfigPath) Then
|
|
Throw New DirectoryNotFoundException($"Path {UserConfigPath} does not exist!")
|
|
End If
|
|
|
|
If Not Directory.Exists(ComputerConfigPath) Then
|
|
Throw New DirectoryNotFoundException($"Path {ComputerConfigPath} does not exist!")
|
|
End If
|
|
|
|
If Not _File.TestPathIsDirectory(UserConfigPath) Then
|
|
Throw New ArgumentException($"Path {UserConfigPath} is not a directory!")
|
|
End If
|
|
|
|
If Not _File.TestPathIsDirectory(ComputerConfigPath) Then
|
|
Throw New ArgumentException($"Path {ComputerConfigPath} is not a directory!")
|
|
End If
|
|
|
|
_Config = LoadConfig()
|
|
End Sub
|
|
|
|
''' <summary>
|
|
''' Save the current config object to `UserConfigPath`
|
|
''' </summary>
|
|
Public Sub Save()
|
|
WriteToFile(_Config, _UserPath)
|
|
End Sub
|
|
|
|
''' <summary>
|
|
''' First check if a user config exists and if it does, load it.
|
|
''' If not, check if a systemwide config exists and and if it does, load it.
|
|
''' Otherwise, create a user config using the default values from the supplied config class `T`
|
|
''' </summary>
|
|
''' <returns></returns>
|
|
Private Function LoadConfig() As T
|
|
Dim oConfig As T
|
|
|
|
If IO.File.Exists(_UserPath) Then
|
|
_Logger.Debug("Loading config from UserPath: {0}", _UserPath)
|
|
_CurrentDataPath = _UserPath
|
|
oConfig = ReadFromFile(_UserPath)
|
|
ElseIf IO.File.Exists(_ComputerPath) Then
|
|
_Logger.Debug("Loading config from ComputerPath: {0}", _ComputerPath)
|
|
_CurrentDataPath = _ComputerPath
|
|
oConfig = ReadFromFile(_ComputerPath)
|
|
Else
|
|
_Logger.Debug("Creating default config in UserPath: {0}", _UserPath)
|
|
_CurrentDataPath = _UserPath
|
|
oConfig = Activator.CreateInstance(_Blueprint.GetType)
|
|
|
|
WriteToFile(_Config, _UserPath)
|
|
End If
|
|
|
|
Return oConfig
|
|
End Function
|
|
|
|
''' <summary>
|
|
''' Serialize a config object to byte array
|
|
''' </summary>
|
|
''' <param name="Data"></param>
|
|
''' <returns></returns>
|
|
Private Function Serialize(Data As T) As Byte()
|
|
Try
|
|
_Logger.Debug("Serializing config object")
|
|
|
|
Using oStream = New MemoryStream()
|
|
_Serializer.Serialize(oStream, Data)
|
|
Return oStream.ToArray()
|
|
End Using
|
|
Catch ex As Exception
|
|
_Logger.Error(ex)
|
|
Throw ex
|
|
End Try
|
|
End Function
|
|
|
|
''' <summary>
|
|
''' Write an object to disk as xml
|
|
''' </summary>
|
|
''' <param name="Data">The object to write</param>
|
|
''' <param name="Path">The file name to write to</param>
|
|
Private Sub WriteToFile(Data As T, Path As String)
|
|
Try
|
|
_Logger.Debug("Saving config to: {0}", Path)
|
|
Dim oBytes = Serialize(Data)
|
|
|
|
Using oFileStream = New FileStream(Path, FileMode.Create, FileAccess.Write)
|
|
oFileStream.Write(oBytes, 0, oBytes.Length)
|
|
oFileStream.Flush()
|
|
End Using
|
|
Catch ex As Exception
|
|
_Logger.Error(ex)
|
|
Throw ex
|
|
End Try
|
|
End Sub
|
|
|
|
''' <summary>
|
|
''' Reads an xml from disk and deserializes to object
|
|
''' </summary>
|
|
''' <returns></returns>
|
|
Private Function ReadFromFile(Path As String) As T
|
|
Try
|
|
_Logger.Debug("Loading config from: {0}", Path)
|
|
Dim oConfig As T
|
|
|
|
Using oReader As New StreamReader(Path)
|
|
oConfig = _Serializer.Deserialize(oReader)
|
|
End Using
|
|
|
|
Return oConfig
|
|
Catch ex As Exception
|
|
_Logger.Error(ex)
|
|
Throw ex
|
|
End Try
|
|
End Function
|
|
End Class
|