Public Class NodeInfo
Public Property X As Double
End Class
Public Class NetNode
Public Property X As Double
End Class
For the models above, I have the following map. The value of the "X" property of the source object is 0.00013. I am expecting the value of "o" to be the same but it is always 0. If I return "s.X" instead of "o" it works fine but I thought that the TMember should have returned the corresponding property value as well.
CreateMap(Of NodeInfo, NetNode)().
ForMember(Function(n) n.X,
Sub(opt As IMemberConfigurationExpression(Of NodeInfo, NetNode, Double))
opt.MapFrom(Function(s As NodeInfo, d As NetNode, o As Double, ctx As ResolutionContext)
Return o
End Function)
End Sub).ReverseMap()
I am using the following overloads.
IMemberConfigurationExpression<TSource, TDestination, TMember>
MapFrom<TResult>(Func<TSource, TDestination, TMember, ResolutionContext, TResult> mappingFunction);
So my full expression for that overload is as following:
Sub IMemberConfigurationExpression(Of NodeInfo,NetNode,Double).MapFrom(Of Double)(mappingFunction As Func(Of NodeInfo,NetNode,Double,ResolutionContext,Double))
Can somebody explain me what I am missing?
CodePudding user response:
It turns out that hat TMember represents the destination member of the destination object.
Thanks to pfx's answer to this question.
Since I needed both source and destination members inside ForAllMembers,
1- I retrieved destination members from ForAllMembers by opt.DestinationMember
Sub(opt As IMemberConfigurationExpression(Of TSource, TDestination, Object))
Dim destinationProperty = TryCast(opt.DestinationMember, PropertyInfo)
Dim destinationProperty = TryCast(opt.DestinationMember, PropertyInfo)
If destinationProperty Is Nothing Then Return
Dim pd = TypeDescriptor.GetProperties(destinationProperty.DeclaringType).OfType(Of PropertyWithParamDescriptor).FirstOrDefault(Function(p) p.Name = destinationProperty.Name)
If pd IsNot Nothing AndAlso pd.CanWrite AndAlso pd.Unit IsNot Nothing AndAlso sourceType.GetProperty(destinationProperty.Name) IsNot Nothing Then
Dim unit = pd.Unit
2- Used ConvertUsing to reach the source member and provided the destination member as parameter to the method I am using in my ConvertUsing.
opt.ConvertUsing(New UnitConvertor(Of Double)(destinationProperty, GetType(TSource), unit))
UnitConvertor
Public Class UnitConvertor(Of T As Structure)
Implements IValueConverter(Of T, Object)
Dim _PropertyInfo As PropertyInfo
Dim _SourceType As Type
Dim _Unit As UnitAttribute
Public Sub New(propertyInfo As PropertyInfo, sourceType As Type, unit As UnitAttribute)
_PropertyInfo = propertyInfo
_SourceType = sourceType
_Unit = unit
End Sub
Public Function Convert(sourceMember As T, ctx As ResolutionContext) As Object Implements IValueConverter(Of T, Object).Convert
Dim unitName = ctx.GetUnitName(_SourceType, _PropertyInfo.Name)
Dim tUnit = If(unitName.HasValue, New Units(_Unit.Unit.UnitType, unitName), CType(Nothing, Units))
Return CType(If(tUnit?.C2SIUnit(System.Convert.ToDouble(sourceMember)), sourceMember), T)
End Function
End Class