Config - version 0.3.0

This commit is contained in:
Jonathan Jenne 2019-04-15 14:01:09 +02:00
parent 696a8ddbf6
commit 9e33f51d3a
6 changed files with 132 additions and 60 deletions

View File

@ -73,7 +73,9 @@
<Import Include="System.Threading.Tasks" />
</ItemGroup>
<ItemGroup>
<Compile Include="ConfigAttributes.vb" />
<Compile Include="ConfigManager.vb" />
<Compile Include="ConfigSample.vb" />
<Compile Include="My Project\AssemblyInfo.vb" />
<Compile Include="My Project\Application.Designer.vb">
<AutoGen>True</AutoGen>
@ -89,7 +91,6 @@
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
<Compile Include="SinceVersionAttribute.vb" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="My Project\Resources.resx">

View File

@ -0,0 +1,5 @@
Public Class ConfigAttributes
Public Class ConnectionStringAttribute
Inherits Attribute
End Class
End Class

View File

@ -1,6 +1,8 @@
Imports System.IO
Imports System.Reflection
Imports System.Xml.Serialization
Imports DigitalData.Modules.Logging
Imports DigitalData.Modules.Config.ConfigAttributes
Public Class ConfigManager(Of T)
Private Const USER_CONFIG_NAME As String = "UserConfig.xml"
@ -11,7 +13,8 @@ Public Class ConfigManager(Of T)
Private ReadOnly _File As Filesystem.File
Private ReadOnly _UserPath As String
Private ReadOnly _ComputerPath As String
Private _CurrentDataPath As String
Private _ForceUserConfig As Boolean
''' <summary>
''' The blueprint class from which the default config is created
@ -21,29 +24,22 @@ Public Class ConfigManager(Of T)
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>
''' <seealso cref="ConfigSample"/>
''' <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)
''' <param name="UserConfigPath">The path to check for a user config file, eg. AppData</param>
''' <param name="ComputerConfigPath">The path to check for a computer config file, eg. ProgramData</param>
''' <param name="ForceUserConfig">Override values from ComputerConfig with UserConfig</param>
Public Sub New(LogConfig As LogConfig, UserConfigPath As String, ComputerConfigPath As String, Optional ForceUserConfig As Boolean = False)
_LogConfig = LogConfig
_Logger = LogConfig.GetLogger()
_File = New Filesystem.File(_LogConfig)
_UserPath = Path.Combine(UserConfigPath, USER_CONFIG_NAME)
_ComputerPath = Path.Combine(ComputerConfigPath, COMPUTER_CONFIG_NAME)
_ForceUserConfig = ForceUserConfig
_Blueprint = Activator.CreateInstance(Of T)
_Serializer = New XmlSerializer(_Blueprint.GetType)
@ -72,58 +68,130 @@ Public Class ConfigManager(Of T)
End Sub
''' <summary>
''' Creates a new instance of the ConfigManager.
''' Creates a new ConfigManager with a single (user)config path
''' </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)
''' </example>
''' <param name="LogConfig">LogConfig instance</param>
''' <param name="ConfigPath">The path to check for a config file, eg. AppData</param>
''' <param name="LogConfig"></param>
''' <param name="ConfigPath"></param>
Public Sub New(LogConfig As LogConfig, ConfigPath As String)
MyClass.New(LogConfig, ConfigPath, ConfigPath)
MyClass.New(LogConfig, ConfigPath, ConfigPath, ForceUserConfig:=True)
End Sub
''' <summary>
''' Save the current config object to `UserConfigPath`
''' </summary>
Public Sub Save()
''' <returns>True if save was successful, False otherwise</returns>
Public Function Save() As Boolean
Try
WriteToFile(_Config, _UserPath)
Return True
Catch ex As Exception
_Logger.Error(ex)
Return False
End Try
End Function
Private Sub CopyValues(Of T)(Source As T, Target As T, Optional ExcludedAttributeTypes As List(Of Type) = Nothing)
Dim oType As Type = GetType(T)
Dim oExcludedAttributeTypes = IIf(IsNothing(ExcludedAttributeTypes), New List(Of Type), ExcludedAttributeTypes)
Dim oProperties = oType.GetProperties().
Where(Function(p) p.CanRead And p.CanWrite).
Where(Function(p)
For Each oAttributeType As Type In oExcludedAttributeTypes
If Attribute.IsDefined(p, oAttributeType) Then
Return False
End If
Next
Return True
End Function)
For Each oProperty As PropertyInfo In oProperties
Dim oValue = oProperty.GetValue(Source, Nothing)
If Not IsNothing(oValue) Then
oProperty.SetValue(Target, oValue, Nothing)
End If
Next
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
' first create an empty/default config object
Dim oConfig = Activator.CreateInstance(_Blueprint.GetType)
' then Try to load computer config
oConfig = LoadComputerConfig(oConfig)
' now try to load userconfig
oConfig = LoadUserConfig(oConfig)
Return oConfig
End Function
If File.Exists(_UserPath) Then
_Logger.Debug("Loading config from UserPath: {0}", _UserPath)
_CurrentDataPath = _UserPath
oConfig = ReadFromFile(_UserPath)
ElseIf File.Exists(_ComputerPath) Then
_Logger.Debug("Loading config from ComputerPath: {0}", _ComputerPath)
_CurrentDataPath = _ComputerPath
oConfig = ReadFromFile(_ComputerPath)
Private Function LoadComputerConfig(ByVal Config As T) As T
If File.Exists(_ComputerPath) Then
Try
Dim oComputerConfig = ReadFromFile(_ComputerPath)
' if a computer config exists, copy values
' from computer config to final config
If Not IsNothing(oComputerConfig) Then
CopyValues(oComputerConfig, Config)
End If
Catch ex As Exception
_Logger.Error(ex)
_Logger.Warn("Computer config could not be loaded!")
End Try
Else
_Logger.Debug("Creating default config in UserPath: {0}", _UserPath)
_CurrentDataPath = _UserPath
oConfig = Activator.CreateInstance(_Blueprint.GetType)
WriteToFile(_Config, _UserPath)
_ForceUserConfig = True
End If
Return Config
End Function
Private Function LoadUserConfig(ByVal Config As T) As T
If File.Exists(_UserPath) Then
Try
Dim oUserConfig = ReadFromFile(_UserPath)
' if user config exists
If Not IsNothing(oUserConfig) Then
Dim oExcludedAttributes As New List(Of Type)
If Not _ForceUserConfig Then
oExcludedAttributes.Add(GetType(ConnectionStringAttribute))
End If
' Copy values from user config to final config
CopyValues(oUserConfig, Config, oExcludedAttributes)
End If
'Dim oConnectionProperty = TestHasAttribute(oConfig, GetType(ConnectionStringAttribute))
Catch ex As Exception
_Logger.Error(ex)
_Logger.Warn("User config could not be loaded!")
End Try
End If
Return Config
End Function
Private Function LoadDefaultConfig() As T
_Logger.Debug("Creating default config in UserPath: {0}", _UserPath)
Dim oConfig = Activator.CreateInstance(_Blueprint.GetType)
Try
WriteToFile(oConfig, _UserPath)
Catch ex As Exception
_Logger.Warn("Could not create default config in UserPath: {0}", _UserPath)
End Try
Return oConfig
End Function
Private Function TestHasAttribute(Config As T, AttributeType As Type) As String
For Each oProperty As PropertyInfo In Config.GetType.GetProperties()
If Attribute.IsDefined(oProperty, GetType(ConnectionStringAttribute)) Then
Return oProperty.Name
End If
Next
Return Nothing
End Function
''' <summary>
''' Serialize a config object to byte array
''' </summary>

7
Config/ConfigSample.vb Normal file
View File

@ -0,0 +1,7 @@
Imports DigitalData.Modules.Config.ConfigAttributes
Public Class ConfigSample
<ConnectionString>
Public Property ConnectionString As String
End Class

View File

@ -31,5 +31,5 @@ Imports System.Runtime.InteropServices
' übernehmen, indem Sie "*" eingeben:
' <Assembly: AssemblyVersion("1.0.*")>
<Assembly: AssemblyVersion("1.0.0.1")>
<Assembly: AssemblyVersion("0.0.3.0")>
<Assembly: AssemblyFileVersion("1.0.0.0")>

View File

@ -1,9 +0,0 @@
Public Class SinceVersionAttribute
Inherits Attribute
Public Version As Version
Public Sub New(Version As String)
Me.Version = New Version(Version)
End Sub
End Class