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("(?[\w\s-]+)(?:\[(?[\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