How to pass a value obtained from a function call within a ForMember() into another one using AutoMapper

Viewed 1218

On CreateMap() I'd like to use the returned value from a function call within a ForMember() to avoid having to call the same function twice.

CreateMap<source, destination>()
                .ForMember(dest => dest.Variable2, opt => opt.MapFrom(src => testFunction(src.Variable1))
                .ForMember(dest => dest.Variable3, opt => opt.MapFrom(src => testFunction(src.Variable1));
1 Answers

You can influence the order in which the properties get mapped via SetMappingOrder.

Ensure that eg. property Variable2 gets mapped via a call to testFunction before property Variable3 gets mapped.
After that, property Variable3 can be mapped from the value already set in property Variable2.

To do so, set the mapping order of Variable2 to eg. 1 and give the one of Variable3 a higher value, eg. 2.

The example below shows that the testFunction has only run once as Variable2 and Variable3 have been given the same Guid value.

var config = new MapperConfiguration(cfg => { 

    cfg.CreateMap<Source, Destination>()
        .ForMember(
            dest => dest.Variable2, 
            opt => {
                opt.SetMappingOrder(1); // Will be mapped first.
                opt.MapFrom(src => testFunction(src.Variable1));
            })
        .ForMember(
            dest => dest.Variable3, 
            opt => {
                opt.SetMappingOrder(2); // Will be mapped second.
                opt.MapFrom((src, dest) => dest.Variable2);
            });
    });

IMapper mapper = new Mapper(config);

var source = new Source {
    Variable1 = "foo"
    };

var destination = mapper.Map<Destination>(source);

Console.WriteLine($"variable2: {destination.Variable2}");
Console.WriteLine($"variable3: {destination.Variable3}");

// variable2: FOO 377dd1f8-ec1e-4f02-87b6-64f0cc47e989
// variable3: FOO 377dd1f8-ec1e-4f02-87b6-64f0cc47e989

public string testFunction(String arg)
{   
    return $"{arg.ToUpper()} {Guid.NewGuid()}";
}

public class Source
{
    public String Variable1 { get; set; }
}

public class Destination
{
    public String Variable2 { get; set; }
    public String Variable3 { get; set; }
}
Related