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" /> <Import Include="System.Threading.Tasks" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="ConfigAttributes.vb" />
<Compile Include="ConfigManager.vb" /> <Compile Include="ConfigManager.vb" />
<Compile Include="ConfigSample.vb" />
<Compile Include="My Project\AssemblyInfo.vb" /> <Compile Include="My Project\AssemblyInfo.vb" />
<Compile Include="My Project\Application.Designer.vb"> <Compile Include="My Project\Application.Designer.vb">
<AutoGen>True</AutoGen> <AutoGen>True</AutoGen>
@ -89,7 +91,6 @@
<DependentUpon>Settings.settings</DependentUpon> <DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput> <DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile> </Compile>
<Compile Include="SinceVersionAttribute.vb" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<EmbeddedResource Include="My Project\Resources.resx"> <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.IO
Imports System.Reflection
Imports System.Xml.Serialization Imports System.Xml.Serialization
Imports DigitalData.Modules.Logging Imports DigitalData.Modules.Logging
Imports DigitalData.Modules.Config.ConfigAttributes
Public Class ConfigManager(Of T) Public Class ConfigManager(Of T)
Private Const USER_CONFIG_NAME As String = "UserConfig.xml" 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 _File As Filesystem.File
Private ReadOnly _UserPath As String Private ReadOnly _UserPath As String
Private ReadOnly _ComputerPath As String Private ReadOnly _ComputerPath As String
Private _CurrentDataPath As String
Private _ForceUserConfig As Boolean
''' <summary> ''' <summary>
''' The blueprint class from which the default config is created ''' 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 Public ReadOnly Property Config As T
''' <summary> ''' <summary>
''' Creates a new instance of the ConfigManager ''' Creates a new instance of the ConfigManager
''' </summary> ''' </summary>
''' <example> ''' <seealso cref="ConfigSample"/>
''' 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="LogConfig">LogConfig instance</param>
''' <param name="UserConfigPath">The first path to check for a config file, eg. AppData</param> ''' <param name="UserConfigPath">The path to check for a user config file, eg. AppData</param>
''' <param name="ComputerConfigPath">The second path to check for a config file, eg. ProgramData</param> ''' <param name="ComputerConfigPath">The path to check for a computer config file, eg. ProgramData</param>
Public Sub New(LogConfig As LogConfig, UserConfigPath As String, ComputerConfigPath As String) ''' <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 _LogConfig = LogConfig
_Logger = LogConfig.GetLogger() _Logger = LogConfig.GetLogger()
_File = New Filesystem.File(_LogConfig) _File = New Filesystem.File(_LogConfig)
_UserPath = Path.Combine(UserConfigPath, USER_CONFIG_NAME) _UserPath = Path.Combine(UserConfigPath, USER_CONFIG_NAME)
_ComputerPath = Path.Combine(ComputerConfigPath, COMPUTER_CONFIG_NAME) _ComputerPath = Path.Combine(ComputerConfigPath, COMPUTER_CONFIG_NAME)
_ForceUserConfig = ForceUserConfig
_Blueprint = Activator.CreateInstance(Of T) _Blueprint = Activator.CreateInstance(Of T)
_Serializer = New XmlSerializer(_Blueprint.GetType) _Serializer = New XmlSerializer(_Blueprint.GetType)
@ -72,58 +68,130 @@ Public Class ConfigManager(Of T)
End Sub End Sub
''' <summary> ''' <summary>
''' Creates a new instance of the ConfigManager. ''' Creates a new ConfigManager with a single (user)config path
''' </summary> ''' </summary>
''' <example> ''' <param name="LogConfig"></param>
''' Public Class Config ''' <param name="ConfigPath"></param>
''' 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>
Public Sub New(LogConfig As LogConfig, ConfigPath As String) Public Sub New(LogConfig As LogConfig, ConfigPath As String)
MyClass.New(LogConfig, ConfigPath, ConfigPath) MyClass.New(LogConfig, ConfigPath, ConfigPath, ForceUserConfig:=True)
End Sub End Sub
''' <summary> ''' <summary>
''' Save the current config object to `UserConfigPath` ''' Save the current config object to `UserConfigPath`
''' </summary> ''' </summary>
Public Sub Save() ''' <returns>True if save was successful, False otherwise</returns>
WriteToFile(_Config, _UserPath) 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 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 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 Private Function LoadComputerConfig(ByVal Config As T) As T
_Logger.Debug("Loading config from UserPath: {0}", _UserPath) If File.Exists(_ComputerPath) Then
_CurrentDataPath = _UserPath Try
oConfig = ReadFromFile(_UserPath) Dim oComputerConfig = ReadFromFile(_ComputerPath)
ElseIf File.Exists(_ComputerPath) Then
_Logger.Debug("Loading config from ComputerPath: {0}", _ComputerPath) ' if a computer config exists, copy values
_CurrentDataPath = _ComputerPath ' from computer config to final config
oConfig = ReadFromFile(_ComputerPath) 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 Else
_Logger.Debug("Creating default config in UserPath: {0}", _UserPath) _ForceUserConfig = True
_CurrentDataPath = _UserPath
oConfig = Activator.CreateInstance(_Blueprint.GetType)
WriteToFile(_Config, _UserPath)
End If 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 Return oConfig
End Function 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> ''' <summary>
''' Serialize a config object to byte array ''' Serialize a config object to byte array
''' </summary> ''' </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: ' übernehmen, indem Sie "*" eingeben:
' <Assembly: AssemblyVersion("1.0.*")> ' <Assembly: AssemblyVersion("1.0.*")>
<Assembly: AssemblyVersion("1.0.0.1")> <Assembly: AssemblyVersion("0.0.3.0")>
<Assembly: AssemblyFileVersion("1.0.0.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