Automapper conditional map from multiple source fields

Viewed 5686

I've got a source class like the following:

public class Source
{
    public Field[] Fields { get; set; }
    public Result[] Results { get; set; }
}

And have a destination class like:

public class Destination
{
    public Value[] Values { get; set; }
}

So I want to map from EITHER Fields or Results to Values depending on which one is not null (only one will ever have a value).

I tried the following map:

CreateMap<Fields, Values>();                
CreateMap<Results, Values>();                

CreateMap<Source, Destination>()                
            .ForMember(d => d.Values, opt =>
            {
                opt.PreCondition(s => s.Fields != null);
                opt.MapFrom(s => s.Fields });
            })
            .ForMember(d => d.Values, opt =>
            {
                opt.PreCondition(s => s.Results != null);
                opt.MapFrom(s => s.Results);
            });

Only issue with this is that it looks if the last .ForMember map doesn't meet the condition it wipes out the mapping result from the first map.

I also thought about doing it as a conditional operator:

opt => opt.MapFrom(s => s.Fields != null ? s.Fields : s.Results)

But obviously they are different types so don't compile.

How can I map to a single property from source properties of different types based on a condition?

Thanks

3 Answers

Following @animalito_maquina answer.

Here is an update for 8.0 Upgrade:

CreateMap<Source, Destination>()
    .ForMember(dest => dest.Values, mo => mo.MapFrom<ConditionalSourceValueResolver>());

And to save you time, ValueResolvers are not supported for Queryable Extensions

ResolveUsing is not available, try this. It's working for me

CreateMap<Source, Destination>()   
.ForMember(opt => opt.value, map => 
map.MapFrom((s, Ariel) => s.Fields != null ? s.Fields : s.Results));
Related