2022-04-06 14:55:15 +02:00

128 lines
5.1 KiB
VB.net

Imports System.Globalization
Imports System.Text.RegularExpressions
Imports AutoMapper
Imports AutoMapper.Configuration
Imports DigitalData.Modules.Logging
Imports MultiTool.Common.Documents.DocumentRow
Public Class Mapper
Private MapperConfig As MapperConfiguration
Private ReadOnly LogConfig As LogConfig
Private ReadOnly Logger As Logger
Public Sub New(pLogConfig As LogConfig)
LogConfig = pLogConfig
Logger = pLogConfig.GetLogger
End Sub
Public Function GetMapper(Of T)(pPropertyMap As Dictionary(Of String, String)) As IMapper
MapperConfig = New MapperConfiguration(CreateMapperConfig(Of T)(pPropertyMap))
MapperConfig.AssertConfigurationIsValid()
Return MapperConfig.CreateMapper()
End Function
Private Function CreateMapperConfig(Of T)(pPropertyMap As Dictionary(Of String, String)) As MapperConfigurationExpression
Logger.Info("Creating mapper config for type [{0}]", GetType(T).Name)
Dim oConfig As New MapperConfigurationExpression()
oConfig.AddProfile(New MappingProfile(Of T)(LogConfig, pPropertyMap))
Return oConfig
End Function
Public Class MappingProfile(Of T)
Inherits Profile
Private ReadOnly LogConfig As LogConfig
Public Overrides ReadOnly Property ProfileName As String
Get
Return "MappingProfile"
End Get
End Property
Public Sub New(pLogConfig As LogConfig, pPropertyMap As Dictionary(Of String, String))
LogConfig = pLogConfig
CreateMap(Of Dictionary(Of String, FieldValue), T).ConvertUsing(New ReportTypeConverter(Of T)(LogConfig, pPropertyMap))
End Sub
End Class
Private Class ReportTypeConverter(Of TDestination)
Implements ITypeConverter(Of Dictionary(Of String, FieldValue), TDestination)
Private ReadOnly PropertyMap As Dictionary(Of String, String)
Private ReadOnly KeyWithSubkey As New Regex("(?<Key>[\w\s-]+)(?:\[(?<Subkey>[\w]+)\])?")
Private ReadOnly Logger As Logger
Public Sub New(pLogConfig As LogConfig, pPropertyMap As Dictionary(Of String, String))
MyBase.New()
Logger = pLogConfig.GetLogger()
PropertyMap = pPropertyMap
End Sub
Public Function Convert(pSource As Dictionary(Of String, FieldValue), pDestination As TDestination, pContext As ResolutionContext) As TDestination Implements ITypeConverter(Of Dictionary(Of String, FieldValue), TDestination).Convert
If pSource Is Nothing Then
Return Nothing
End If
Dim oResult = Activator.CreateInstance(Of TDestination)
Logger.Info("Mapping object of Type [{0}]", GetType(TDestination).Name)
For Each oMapItem As KeyValuePair(Of String, String) In PropertyMap
Try
' SourceKey will be something like 'Fakt_Kontonummer[Final]'
' DestinationKey will be something like 'Text1'
Dim oSourceKeyCombined As String = oMapItem.Key
Dim oDestinationKey As String = oMapItem.Value
' Resolve SourceKey into Key and Subkey
Dim oMatch As Match = KeyWithSubkey.Match(oSourceKeyCombined)
Dim oSourceKey As String = oMatch.Groups("Key")?.Value
Dim oSourceSubkey As String = oMatch.Groups("Subkey")?.Value
' Set property value if property exists in source
If pSource.ContainsKey(oSourceKey) Then
' Try to get the value from 'source'
Dim oFieldValue As FieldValue = pSource.Item(oSourceKey)
' Get the destination property by DestinationKey
Dim oProperty = GetType(TDestination).
GetProperties().
SingleOrDefault(Function(p) p.Name = oDestinationKey)
' Set the property if it exists
If oProperty IsNot Nothing Then
Dim oValue = GetFieldValue(oFieldValue, oSourceSubkey)
Logger.Info("Transferring value [{0}] from [{1}] -> [{2}]", oValue, oSourceKeyCombined, oDestinationKey)
oProperty.SetValue(oResult, oValue)
Else
Logger.Warn("Property [{0}] does not exist in destination object. Possible error in configuration.", oDestinationKey)
End If
End If
Catch ex As Exception
Logger.Warn("Could not transfer key [{0}] to destination object", oMapItem.Key)
Logger.Error(ex)
End Try
Next
Return oResult
End Function
Private Function GetFieldValue(pValue As FieldValue, pKey As String) As String
If pKey = "Original" Then
Return pValue.Original
ElseIf pKey = "External" Then
Return pValue.External
Else
Return pValue.Final
End If
End Function
End Class
End Class