MONSTER: Rename Monorepo to Modules, only keep Projects under Modules.*

This commit is contained in:
Jonathan Jenne
2022-09-29 13:46:00 +02:00
parent e87b97bfec
commit 042bbce9f4
1557 changed files with 380 additions and 160017 deletions

131
Config/Config.vbproj Normal file
View File

@@ -0,0 +1,131 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{44982F9B-6116-44E2-85D0-F39650B1EF99}</ProjectGuid>
<OutputType>Library</OutputType>
<RootNamespace>DigitalData.Modules.Config</RootNamespace>
<AssemblyName>DigitalData.Modules.Config</AssemblyName>
<FileAlignment>512</FileAlignment>
<MyType>Windows</MyType>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<DefineDebug>true</DefineDebug>
<DefineTrace>true</DefineTrace>
<OutputPath>bin\Debug\</OutputPath>
<DocumentationFile>DigitalData.Modules.Config.xml</DocumentationFile>
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<DefineDebug>false</DefineDebug>
<DefineTrace>true</DefineTrace>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DocumentationFile>DigitalData.Modules.Config.xml</DocumentationFile>
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
</PropertyGroup>
<PropertyGroup>
<OptionExplicit>On</OptionExplicit>
</PropertyGroup>
<PropertyGroup>
<OptionCompare>Binary</OptionCompare>
</PropertyGroup>
<PropertyGroup>
<OptionStrict>Off</OptionStrict>
</PropertyGroup>
<PropertyGroup>
<OptionInfer>On</OptionInfer>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.CSharp" />
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
<HintPath>..\packages\NLog.4.7.15\lib\net45\NLog.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Configuration" />
<Reference Include="System.Data" />
<Reference Include="System.IO.Compression" />
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.ServiceModel" />
<Reference Include="System.Transactions" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Net.Http" />
</ItemGroup>
<ItemGroup>
<Import Include="Microsoft.VisualBasic" />
<Import Include="System" />
<Import Include="System.Collections" />
<Import Include="System.Collections.Generic" />
<Import Include="System.Data" />
<Import Include="System.Diagnostics" />
<Import Include="System.Linq" />
<Import Include="System.Xml.Linq" />
<Import Include="System.Threading.Tasks" />
</ItemGroup>
<ItemGroup>
<Compile Include="ConfigAttributes.vb" />
<Compile Include="ConfigManager.vb" />
<Compile Include="ConfigSample.vb" />
<Compile Include="ConfigUtils.vb" />
<Compile Include="My Project\AssemblyInfo.vb" />
<Compile Include="My Project\Application.Designer.vb">
<AutoGen>True</AutoGen>
<DependentUpon>Application.myapp</DependentUpon>
</Compile>
<Compile Include="My Project\Resources.Designer.vb">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Include="My Project\Settings.Designer.vb">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="My Project\Resources.resx">
<Generator>VbMyResourcesResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.vb</LastGenOutput>
<CustomToolNamespace>My.Resources</CustomToolNamespace>
<SubType>Designer</SubType>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<None Include="My Project\Application.myapp">
<Generator>MyApplicationCodeGenerator</Generator>
<LastGenOutput>Application.Designer.vb</LastGenOutput>
</None>
<None Include="My Project\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<CustomToolNamespace>My</CustomToolNamespace>
<LastGenOutput>Settings.Designer.vb</LastGenOutput>
</None>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Encryption\Encryption.vbproj">
<Project>{8a8f20fc-c46e-41ac-bee7-218366cfff99}</Project>
<Name>Encryption</Name>
</ProjectReference>
<ProjectReference Include="..\Filesystem\Filesystem.vbproj">
<Project>{991d0231-4623-496d-8bd0-9ca906029cbc}</Project>
<Name>Filesystem</Name>
</ProjectReference>
<ProjectReference Include="..\Logging\Logging.vbproj">
<Project>{903b2d7d-3b80-4be9-8713-7447b704e1b0}</Project>
<Name>Logging</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.VisualBasic.targets" />
</Project>

View File

@@ -0,0 +1,35 @@
Public Class ConfigAttributes
''' <summary>
''' The primary connection string. Will not be saved to userconfig.
''' </summary>
Public Class ConnectionStringAttribute
Inherits Attribute
End Class
''' <summary>
''' The test connection string. Will not be saved to userconfig.
''' </summary>
Public Class ConnectionStringTestAttribute
Inherits Attribute
End Class
''' <summary>
''' The app serverSQL connection string. Will not be saved to userconfig.
''' </summary>
Public Class ConnectionStringAppServerAttribute
Inherits Attribute
End Class
''' <summary>
''' The EDMIapp server . Will not be saved to userconfig.
''' </summary>
Public Class EDMIAppServerAttribute
Inherits Attribute
End Class
''' <summary>
''' Global setting. Will not be saved to userconfig.
''' </summary>
Public Class GlobalSettingAttribute
Inherits Attribute
End Class
End Class

388
Config/ConfigManager.vb Normal file
View File

@@ -0,0 +1,388 @@
Imports System.IO
Imports System.Reflection
Imports System.Xml.Serialization
Imports DigitalData.Modules.Logging
Imports DigitalData.Modules.Encryption
Imports DigitalData.Modules.Config.ConfigAttributes
Public Class ConfigManager(Of T)
Private Const USER_CONFIG_NAME As String = "UserConfig.xml"
Private Const COMPUTER_CONFIG_NAME As String = "ComputerConfig.xml"
Private Const APP_CONFIG_NAME As String = "AppConfig.xml"
Private ReadOnly _LogConfig As LogConfig
Private ReadOnly _Logger As Logger
Private ReadOnly _File As Filesystem.File
Private ReadOnly _UserDirectory As String
Private ReadOnly _UserConfigPath As String
Private ReadOnly _ComputerDirectory As String
Private ReadOnly _ComputerConfigPath As String
Private ReadOnly _AppConfigDirectory As String
Private ReadOnly _AppConfigPath As String
Private ReadOnly _TestMode As Boolean = False
Private ReadOnly _Blueprint As T
Private ReadOnly _BlueprintType As Type
Private ReadOnly _Serializer As XmlSerializer
Private ReadOnly _ExcludedAttributes = New List(Of Type) From {
GetType(ConnectionStringAttribute),
GetType(ConnectionStringAppServerAttribute),
GetType(ConnectionStringTestAttribute),
GetType(EDMIAppServerAttribute),
GetType(GlobalSettingAttribute)
}
Private ReadOnly _ConnectionStringAttributes = New List(Of Type) From {
GetType(ConnectionStringAttribute),
GetType(ConnectionStringAppServerAttribute),
GetType(ConnectionStringTestAttribute)
}
''' <summary>
''' Signals that all properties will be written to (and read from) the UserConfig.xml
'''
''' If Value is `True`:
''' - AppConfig.xml does NOT exist
''' - ComputerConfig.xml does NOT exist
''' - ConnectionStrings will be saved to or read from UserConfig.xml
'''
''' If Value is `False`:
''' - No ConnectionStrings will be saved to or read from UserConfig.xml
'''
''' Can be overwritten by optional parameter `ForceUserConfig`
''' </summary>
Private _WriteAllValuesToUserConfig As Boolean = False
''' <summary>
''' Returns the currently loaded config object
''' </summary>
''' <returns></returns>
Public ReadOnly Property Config As T
''' <summary>
''' Path to the current user config.
''' </summary>
''' <returns></returns>
Public ReadOnly Property UserConfigPath As String
Get
Return _UserConfigPath
End Get
End Property
''' <summary>
''' Path to the current computer config.
''' </summary>
''' <returns></returns>
Public ReadOnly Property ComputerConfigPath As String
Get
Return _ComputerConfigPath
End Get
End Property
''' <summary>
''' Path to the current Application config.
''' </summary>
''' <returns></returns>
Public ReadOnly Property AppConfigPath As String
Get
Return _AppConfigPath
End Get
End Property
''' <summary>
''' Creates a new instance of the ConfigManager
''' </summary>
''' <seealso cref="ConfigSample"/>
''' <param name="LogConfig">LogConfig instance</param>
''' <param name="UserConfigPath">The path to check for a user config file, eg. AppData (Usually Application.UserAppDataPath or Application.LocalUserAppDataPath)</param>
''' <param name="ComputerConfigPath">The path to check for a computer config file, eg. ProgramData (Usually Application.CommonAppDataPath)</param>
''' <param name="ApplicationStartupPath">The path to check for a third config file. This is useful when running the Application in an environment where AppData/ProgramData directories are not available</param>
''' <param name="ForceUserConfig">Override values from ComputerConfig with UserConfig</param>
Public Sub New(LogConfig As LogConfig, UserConfigPath As String, ComputerConfigPath As String, Optional ApplicationStartupPath As String = "", Optional ForceUserConfig As Boolean = False)
_LogConfig = LogConfig
_Logger = LogConfig.GetLogger()
_File = New Filesystem.File(_LogConfig)
_Blueprint = Activator.CreateInstance(Of T)
_BlueprintType = _Blueprint.GetType
_Serializer = New XmlSerializer(_BlueprintType)
_UserDirectory = _File.CreateDirectory(UserConfigPath)
_UserConfigPath = Path.Combine(_UserDirectory, USER_CONFIG_NAME)
If ComputerConfigPath <> String.Empty Then
If IO.File.Exists(ComputerConfigPath) Then
_ComputerDirectory = _File.CreateDirectory(ComputerConfigPath, False)
Else
_ComputerDirectory = ComputerConfigPath
End If
_ComputerConfigPath = Path.Combine(_ComputerDirectory, COMPUTER_CONFIG_NAME)
End If
If ApplicationStartupPath <> String.Empty Then
_Logger.Info($"AppConfig is being used: [{ApplicationStartupPath}]")
_AppConfigPath = Path.Combine(ApplicationStartupPath, APP_CONFIG_NAME)
End If
_WriteAllValuesToUserConfig = ForceUserConfig
_Config = LoadConfig()
End Sub
''' <summary>
''' Creates a new ConfigManager with a single (user)config path
''' </summary>
''' <param name="LogConfig">LogConfig instance</param>
''' <param name="ConfigPath">The path to check for a user config file, eg. AppData (Usually Application.UserAppDataPath or Application.LocalUserAppDataPath)</param>
Public Sub New(LogConfig As LogConfig, ConfigPath As String)
MyClass.New(LogConfig, ConfigPath, String.Empty, String.Empty, ForceUserConfig:=True)
End Sub
''' <summary>
''' Save the current config object to `UserConfigPath`
''' </summary>
''' <param name="ForceAll">Force saving all attributes including the attributes marked as excluded</param>
''' <returns>True if save was successful, False otherwise</returns>
Public Function Save(Optional ForceAll As Boolean = False) As Boolean
Try
WriteToFile(Config, _UserConfigPath, ForceAll)
Return True
Catch ex As Exception
_Logger.Error(ex)
Return False
End Try
End Function
''' <summary>
''' Reloads the config object from file.
''' </summary>
''' <returns>True if reload was successful, False otherwise</returns>
Public Function Reload() As Boolean
Try
_Config = LoadConfig()
Return True
Catch ex As Exception
_Logger.Error(ex)
Return False
End Try
End Function
''' <summary>
''' Copies all properties from Source to Target, except those who have an attribute
''' listed in ExcludedAttributeTypes
''' </summary>
''' <param name="Source">Source config object</param>
''' <param name="Target">Target config object</param>
''' <param name="ExcludedAttributeTypes">List of Attribute type to exclude</param>
Private Sub CopyValues(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
' TODO: Process individual Subfields of class-objects
' to allow for the PasswordAttribute to be set on class properies aka nested properties
Dim oValue = oProperty.GetValue(Source, Nothing)
If Not IsNothing(oValue) Then
oProperty.SetValue(Target, oValue, Nothing)
End If
Next
End Sub
''' <summary>
''' Filters a config object by copying all values except `ExcludedAttributeTypes`
''' </summary>
''' <param name="Data">Config object</param>
''' <param name="ExcludedAttributeTypes">List of Attribute type to exclude</param>
''' <returns></returns>
Private Function FilterValues(ByVal Data As T, ExcludedAttributeTypes As List(Of Type)) As T
Dim oResult As T = Activator.CreateInstance(Of T)
CopyValues(Data, oResult, ExcludedAttributeTypes)
Return oResult
End Function
Private Function LoadConfig() As T
' first create an empty/default config object
Dim oConfig As T = Activator.CreateInstance(_BlueprintType)
' try to load the special app config
oConfig = LoadAppConfig(oConfig)
' try to load the computer config
oConfig = LoadComputerConfig(oConfig)
' now try to load userconfig
oConfig = LoadUserConfig(oConfig)
Return oConfig
End Function
Private Function LoadAppConfig(ByVal Config As T) As T
If Not String.IsNullOrEmpty(_AppConfigPath) AndAlso File.Exists(_AppConfigPath) Then
Try
Dim oAppConfig = ReadFromFile(_AppConfigPath)
CopyValues(oAppConfig, Config)
_Logger.Info("AppConfig exists and will be used. [{0}]", _AppConfigPath)
Catch ex As Exception
_Logger.Error(ex)
_Logger.Warn("ApplicationConfig could not be loaded!")
End Try
_WriteAllValuesToUserConfig = False
Else
_Logger.Debug("ApplicationConfig does not exist.")
_WriteAllValuesToUserConfig = True
End If
Return Config
End Function
Private Function LoadComputerConfig(ByVal Config As T) As T
If _WriteAllValuesToUserConfig = False Then
_Logger.Info("AppConfig exists. ComputerConfig will NOT be used")
ElseIf File.Exists(_ComputerConfigPath) Then
Try
Dim oComputerConfig = ReadFromFile(_ComputerConfigPath)
CopyValues(oComputerConfig, Config)
_Logger.Info("ComputerConfig exists and will be used. [{0}]", _ComputerConfigPath)
Catch ex As Exception
_Logger.Error(ex)
_Logger.Warn("Computer config could not be loaded!")
End Try
_WriteAllValuesToUserConfig = False
Else
_Logger.Debug("Computer config does not exist.")
_WriteAllValuesToUserConfig = True
End If
Return Config
End Function
Private Function LoadUserConfig(ByVal Config As T) As T
If File.Exists(_UserConfigPath) Then
Try
Dim oUserConfig = ReadFromFile(_UserConfigPath)
_Logger.Debug("UserConfig exists and will be used. [{0}]", _UserConfigPath)
' if user config exists
If Not IsNothing(oUserConfig) Then
' Copy values from user config to final config
If _WriteAllValuesToUserConfig Then
CopyValues(oUserConfig, Config, New List(Of Type))
Else
CopyValues(oUserConfig, Config, _ExcludedAttributes)
End If
End If
Catch ex As Exception
_Logger.Error(ex)
_Logger.Warn("User config could not be loaded!")
End Try
Else
_Logger.Debug("User config does not exist. Default config will be created")
WriteToFile(Config, _UserConfigPath, False)
End If
Return Config
End Function
Private Function TestHasAttribute(Config As T, AttributeType As Type) As Boolean
For Each oProperty As PropertyInfo In Config.GetType.GetProperties()
If Attribute.IsDefined(oProperty, GetType(ConnectionStringAttribute)) Then
Return True
End If
Next
Return False
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)
_Logger.Debug("Object serialized.")
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, ForceAll As Boolean)
Try
_Logger.Debug("Saving config to: {0}", Path)
' If config was loaded from computer config,
' DO NOT save connection string, etc. to user config
If _WriteAllValuesToUserConfig = False And ForceAll = False Then
Data = FilterValues(Data, _ExcludedAttributes)
End If
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.Warn("Could not save config to {0}", Path)
_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
' If oConfig is Nothing, a config file was created but nothing was written to it.
' In this case we need to create oConfig from defaults so we have at least some config object
If oConfig Is Nothing Then
_Logger.Debug("Config file is valid but empty. Loading default values")
oConfig = Activator.CreateInstance(_BlueprintType)
End If
Return oConfig
Catch ex As Exception
_Logger.Warn("Could not load config from {0}", Path)
_Logger.Error(ex)
Throw ex
End Try
End Function
End Class

20
Config/ConfigSample.vb Normal file
View File

@@ -0,0 +1,20 @@
Imports DigitalData.Modules.Config.ConfigAttributes
Public Class ConfigSample
<ConnectionString>
Public Property ConnectionString As String
<ConnectionStringTest>
Public Property ConnectionStringTest As String
<ConnectionStringAppServer>
Public Property ConnectionStringAppServer As String
<EDMIAppServer>
Public Property EDMIAppServer As String
<GlobalSetting>
Public Property GlobalSetting As Integer
Public Property SomeSetting As Boolean
End Class

119
Config/ConfigUtils.vb Normal file
View File

@@ -0,0 +1,119 @@
Imports DigitalData.Modules.Logging
Public Class ConfigUtils
Private _Logger As Logger
Private _File As Filesystem.File
Private Const MIGRATE_DIRECTORY As String = "Migrate"
Public Sub New(LogConfig As LogConfig)
_Logger = LogConfig.GetLogger()
_File = New Filesystem.File(LogConfig)
End Sub
Public Function TestMigrationNeeded(TargetDirectory As String) As Boolean
If IO.Directory.Exists(TargetDirectory) Then
Return False
Else
Return True
End If
End Function
Public Sub MigrateConfig(SourceDirectory As String, TargetDirectory As String, Optional FilePattern As String = "*.*")
If IO.Directory.Exists(TargetDirectory) Then
_Logger.Warn("Config Migration aborted because new config directory [{0}] already exists!", TargetDirectory)
Exit Sub
End If
_Logger.Debug("Creating TargetDirectory [{0}]", TargetDirectory)
' Create target directory
Try
IO.Directory.CreateDirectory(TargetDirectory)
Catch ex As Exception
_Logger.Warn("Config Migration aborted because new config directory [{0}] could not be created!", TargetDirectory)
_Logger.Error(ex)
Exit Sub
End Try
' Create Migration directory
Dim oMigrationDirectory = IO.Path.Combine(SourceDirectory, MIGRATE_DIRECTORY)
_Logger.Debug("Creating MigrationDirectory [{0}]", oMigrationDirectory)
Try
IO.Directory.CreateDirectory(oMigrationDirectory)
Catch ex As Exception
_Logger.Warn("Config Migration aborted because migration directory [{0}] could not be created!", oMigrationDirectory)
_Logger.Error(ex)
Exit Sub
End Try
' Copy individual files from top level directory
For Each oPath In IO.Directory.EnumerateFiles(SourceDirectory, FilePattern)
Dim oFileInfo = New IO.FileInfo(oPath)
_Logger.NewBlock($"File {oFileInfo.Name}")
_Logger.Debug("Processing file [{0}]", oFileInfo.Name)
_Logger.Debug("Copying [{0}] to TargetDirectory..", oFileInfo.Name)
' Copy to target directory
Try
IO.File.Copy(oPath, IO.Path.Combine(TargetDirectory, oFileInfo.Name))
Catch ex As Exception
_Logger.Warn("Could not move old config file {0} to new config location {1}", oFileInfo.Name, TargetDirectory)
_Logger.Error(ex)
End Try
_Logger.Debug("Moving [{0}] to MigrationDirectory..", oFileInfo.Name)
' Move to migration directory
Try
IO.File.Move(oPath, IO.Path.Combine(oMigrationDirectory, oFileInfo.Name))
Catch ex As Exception
_Logger.Warn("Could not move old config file {0} to migration directory {1}", oFileInfo.Name, oMigrationDirectory)
_Logger.Error(ex)
End Try
Next
For Each oDirectoryPath In IO.Directory.EnumerateDirectories(SourceDirectory, "*", IO.SearchOption.TopDirectoryOnly)
Dim oDirInfo As New IO.DirectoryInfo(oDirectoryPath)
_Logger.NewBlock($"Directory {oDirInfo.Name}")
_Logger.Debug("Processing directory [{0}]", oDirInfo.Name)
' Don't copy TargetDirectory if subpath of SourceDirectory or if MigrationDirectory
If oDirInfo.FullName = TargetDirectory Or oDirInfo.FullName = oMigrationDirectory Then
_Logger.Debug("Directory [{0}] should not be copied. Skipping.", oDirInfo.Name)
Continue For
End If
' Copy directory to TargetDirectory
Dim oNewDirectoryPath = IO.Path.Combine(TargetDirectory, oDirInfo.Name)
_Logger.Debug("Copying [{0}] to TargetDirectory..", oDirInfo.Name)
Try
_File.CopyDirectory(oDirInfo.FullName, oNewDirectoryPath, True)
Catch ex As Exception
_Logger.Warn("Could not move directory [{0}] to new path [{1}]", oDirInfo.FullName, oNewDirectoryPath)
_Logger.Error(ex)
End Try
_Logger.Debug("Copying [{0}] to MigrationDirectory..", oDirInfo.Name)
' Copy directory to MigrationDirectory
Dim oMigrationDirectoryPath = IO.Path.Combine(oMigrationDirectory, oDirInfo.Name)
Try
_File.CopyDirectory(oDirInfo.FullName, oMigrationDirectoryPath, True)
Catch ex As Exception
_Logger.Error(ex)
_Logger.Warn("Could not move directory [{0}] to migration directory [{1}]", oDirInfo.FullName, oMigrationDirectoryPath)
End Try
_Logger.Debug("Deleting [{0}]..", oDirInfo.Name)
' Delete directory
Try
IO.Directory.Delete(oDirInfo.FullName, True)
Catch ex As Exception
_Logger.Error(ex)
_Logger.Warn("Could not delete directory [{0}]", oDirInfo.FullName)
End Try
Next
End Sub
End Class

View File

@@ -0,0 +1,13 @@
'------------------------------------------------------------------------------
' <auto-generated>
' Dieser Code wurde von einem Tool generiert.
' Laufzeitversion:4.0.30319.42000
'
' Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
' der Code erneut generiert wird.
' </auto-generated>
'------------------------------------------------------------------------------
Option Strict On
Option Explicit On

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<MyApplicationData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<MySubMain>false</MySubMain>
<SingleInstance>false</SingleInstance>
<ShutdownMode>0</ShutdownMode>
<EnableVisualStyles>true</EnableVisualStyles>
<AuthenticationMode>0</AuthenticationMode>
<ApplicationType>1</ApplicationType>
<SaveMySettingsOnExit>true</SaveMySettingsOnExit>
</MyApplicationData>

View File

@@ -0,0 +1,35 @@
Imports System
Imports System.Reflection
Imports System.Runtime.InteropServices
' Allgemeine Informationen über eine Assembly werden über die folgenden
' Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
' die einer Assembly zugeordnet sind.
' Werte der Assemblyattribute überprüfen
<Assembly: AssemblyTitle("Modules.Config")>
<Assembly: AssemblyDescription("")>
<Assembly: AssemblyCompany("")>
<Assembly: AssemblyProduct("Modules.Config")>
<Assembly: AssemblyCopyright("Copyright © 2022")>
<Assembly: AssemblyTrademark("")>
<Assembly: ComVisible(False)>
'Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird.
<Assembly: Guid("6e67fba4-81d1-44bb-81f4-16ad52822192")>
' Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten:
'
' Hauptversion
' Nebenversion
' Buildnummer
' Revision
'
' Sie können alle Werte angeben oder Standardwerte für die Build- und Revisionsnummern verwenden,
' übernehmen, indem Sie "*" eingeben:
' <Assembly: AssemblyVersion("1.0.*")>
<Assembly: AssemblyVersion("1.1.4.1")>
<Assembly: AssemblyFileVersion("1.1.4.1")>

63
Config/My Project/Resources.Designer.vb generated Normal file
View File

@@ -0,0 +1,63 @@
'------------------------------------------------------------------------------
' <auto-generated>
' Dieser Code wurde von einem Tool generiert.
' Laufzeitversion:4.0.30319.42000
'
' Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
' der Code erneut generiert wird.
' </auto-generated>
'------------------------------------------------------------------------------
Option Strict On
Option Explicit On
Imports System
Namespace My.Resources
'Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert
'-Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert.
'Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen
'mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu.
'''<summary>
''' Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw.
'''</summary>
<Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0"), _
Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _
Global.Microsoft.VisualBasic.HideModuleNameAttribute()> _
Friend Module Resources
Private resourceMan As Global.System.Resources.ResourceManager
Private resourceCulture As Global.System.Globalization.CultureInfo
'''<summary>
''' Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird.
'''</summary>
<Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
Friend ReadOnly Property ResourceManager() As Global.System.Resources.ResourceManager
Get
If Object.ReferenceEquals(resourceMan, Nothing) Then
Dim temp As Global.System.Resources.ResourceManager = New Global.System.Resources.ResourceManager("DigitalData.Modules.Config.Resources", GetType(Resources).Assembly)
resourceMan = temp
End If
Return resourceMan
End Get
End Property
'''<summary>
''' Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle
''' Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden.
'''</summary>
<Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
Friend Property Culture() As Global.System.Globalization.CultureInfo
Get
Return resourceCulture
End Get
Set
resourceCulture = value
End Set
End Property
End Module
End Namespace

View File

@@ -0,0 +1,117 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

73
Config/My Project/Settings.Designer.vb generated Normal file
View File

@@ -0,0 +1,73 @@
'------------------------------------------------------------------------------
' <auto-generated>
' Dieser Code wurde von einem Tool generiert.
' Laufzeitversion:4.0.30319.42000
'
' Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
' der Code erneut generiert wird.
' </auto-generated>
'------------------------------------------------------------------------------
Option Strict On
Option Explicit On
Namespace My
<Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _
Global.System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.7.0.0"), _
Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
Partial Friend NotInheritable Class MySettings
Inherits Global.System.Configuration.ApplicationSettingsBase
Private Shared defaultInstance As MySettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings()),MySettings)
#Region "Automatische My.Settings-Speicherfunktion"
#If _MyType = "WindowsForms" Then
Private Shared addedHandler As Boolean
Private Shared addedHandlerLockObject As New Object
<Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
Private Shared Sub AutoSaveSettings(sender As Global.System.Object, e As Global.System.EventArgs)
If My.Application.SaveMySettingsOnExit Then
My.Settings.Save()
End If
End Sub
#End If
#End Region
Public Shared ReadOnly Property [Default]() As MySettings
Get
#If _MyType = "WindowsForms" Then
If Not addedHandler Then
SyncLock addedHandlerLockObject
If Not addedHandler Then
AddHandler My.Application.Shutdown, AddressOf AutoSaveSettings
addedHandler = True
End If
End SyncLock
End If
#End If
Return defaultInstance
End Get
End Property
End Class
End Namespace
Namespace My
<Global.Microsoft.VisualBasic.HideModuleNameAttribute(), _
Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute()> _
Friend Module MySettingsProperty
<Global.System.ComponentModel.Design.HelpKeywordAttribute("My.Settings")> _
Friend ReadOnly Property Settings() As Global.DigitalData.Modules.Config.My.MySettings
Get
Return Global.DigitalData.Modules.Config.My.MySettings.Default
End Get
End Property
End Module
End Namespace

View File

@@ -0,0 +1,7 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" UseMySettingsClassName="true">
<Profiles>
<Profile Name="(Default)" />
</Profiles>
<Settings />
</SettingsFile>

70
Config/SampleConfig.vb Normal file
View File

@@ -0,0 +1,70 @@
Imports Config
Imports NLog
''' <summary>
''' Sample Config Class inheriting from BaseConfig
'''
'''
'''
''' Things this class should do:
'''
''' - Provide defaults for all values
''' - Load the current config using the LoadConfig method of BaseConfig
''' - If no configfile was found, it should create a new datatable with only default values
''' - If a configfile was found, it should merge the values from this file with the defaults from this class
''' - For each propertyname defined in PropertyNames
''' - Check for existing value in datatable
''' - If a value is present, use it
''' - If no value is exists, use the default value
''' - Assign the resulting values to class properties
''' - Save the new config to disk
''' </summary>
Public Class SampleConfig
Inherits BaseConfig
Private _logger As Logger
Public ReadOnly ConnectionString As String
Public ReadOnly UniversalViewer As String
Public Overloads ReadOnly Property PropertyNames As Dictionary(Of String, String)
Get
Return New Dictionary(Of String, String) From {
{"ConnectionString", ""},
{"UniversalViewer", ""}
}
End Get
End Property
Public Sub New(LogFactory As LogFactory)
MyBase.New(LogFactory)
_logger = LogFactory.GetCurrentClassLogger()
' Load the existing values from the config file into PropertyNames
' overwriting the default values
Dim oDataTable = LoadConfig()
For Each oRow As DataRow In oDataTable.Rows
Dim oValue = oRow.Item(_configValue)
Dim oKey = oRow.Item(_configKey)
PropertyNames.Item(oKey) = oValue
Next
' Assign the merged properties to class properties, optionally converting them beforehand
For Each oProperty As KeyValuePair(Of String, String) In PropertyNames
Select Case oProperty.Key
Case "ConnectionString"
ConnectionString = oProperty.Value
Case "UniversalViewer"
UniversalViewer = oProperty.Value
Case Else
_logger.Warn("Property {0} was found in PropertyNames but was not assigned to a config property", oProperty.Key)
End Select
Next
' Convert the dictionary back to a datatable and save it
SaveConfig(ConvertToDataTable(PropertyNames))
End Sub
End Class

4
Config/packages.config Normal file
View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="NLog" version="4.7.15" targetFramework="net461" />
</packages>