Search code examples
c#.netmappingautomapper

Automapper TMember doesn't get the expected value


Models

public class NodeInfo
{
    public double X { get; set; }
}

public class NetNode
{
    public double X { get; set; }
}

For the models above, I have the following map. Say the value of the "X" property of the source object is 5. I am expecting the value of "o" to be 5 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.

Mapper Profile

public class ProfileBase : Profile
{
    public ProfileBase()
    {
        CreateMap<NodeInfo, NetNode>()
        .ForMember(n => n.X, opt => opt.MapFrom((s, d, o, ctx) => o)).ReverseMap();
    }
}

I am using the following overloads for the mapping above.

IMemberConfigurationExpression<TSource, TDestination, TMember>

MapFrom<TResult>(Func<TSource, TDestination, TMember, ResolutionContext, TResult> mappingFunction);

Execution

var config = new MapperConfiguration(cfg => {
    cfg.AddProfile(new ProfileBase());
});

IMapper mapper = config.CreateMapper();

NodeInfo nodeInfo = new() { X = 5 };
NetNode netNode;

netNode = mapper.Map<NetNode>(nodeInfo);
//netNode.X should be 5 but it is 0
//change the "=> o" in the profile to "=> s.X" and it returns 5

Solution

  • That TMember represents the destination member of the destination object, which is the 0 value of the X property of the the newly instantiated NetNode instance.

    From the documentation on GitHub:

    Map destination member using a custom function.
    Access the source, destination object, destination member, and context.

    /// <summary>
    /// Map destination member using a custom function. Access the source, destination object, destination member, and context.
    /// </summary>
    /// <remarks>Not used for LINQ projection (ProjectTo)</remarks>
    /// <param name="mappingFunction">Function to map to destination member</param>
    void MapFrom<TResult>(Func<TSource, TDestination, TMember, ResolutionContext, TResult> mappingFunction);