Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Conditionally mapping one source type to two destination types

I have a source DTO like this

public class Member 
{
    public string MemberId {get;set;}
    public string MemberType {get;set;}
    public string Name {get;set;}
}

The member type can be "Person" or "Company".

And two destination classes like this

public class PersonMember 
{
    public int PersonMemberId {get;set;}
    public string Name {get;set;}
}

public class CompanyMember 
{
    public int CompanyMemberId {get;set;}
    public string Name {get;set;}
}

I want to use Automapper to check what the value of MemberType is in the source class and depending on that type, map to one of the two destination types.

I saw the example of conditionally mapping, but it maps the field it performs the conditional check on. I want to check the condition and map a different field.

var config = new MapperConfiguration(cfg => {
  cfg.CreateMap<Foo,Bar>()
    .ForMember(dest => dest.baz, opt => opt.Condition(src => (src.baz >= 0))); 
});

My goal is something like this -

cfg.CreateMap<Member, PersonMember>()
.ForMember(dest => PersonMember.PersonMemberId, opt => if the source.MemberType == "Person" perform mapping from MemberId, otherwise do nothing);

cfg.CreateMap<Member, CompanyMember>()
.ForMember(dest => CompanyMember.CompanyMemberId, opt => if the source.MemberType == "Company" perform mapping from MemberId, otherwise do nothing);
like image 545
Bryan Avatar asked Sep 10 '25 12:09

Bryan


1 Answers

Introduce some base class Member. Inherit PersonMember, CompanyMember from the new base class.

Then define these mappings:

cfg.CreateMap<Dto.Member, Member>()
    .ConstructUsing((memberDto, context) => {
    switch (memberDto.MemberType)
    {
        case "PersonMember":
            return context.Mapper.Map<PersonMember>(memberDto);
        case "CompanyMember":
            return context.Mapper.Map<CompanyMember>(memberDto);
        default:
            throw new ArgumentOutOfRangeException($"Unknown MemberType {memberDto.MemberType}");
    }
});

cfg.CreateMap<Dto.Member, PersonMember>()
    .ForMember(dest => PersonMember.PersonMemberId,
               opt => opt.MapFrom(src => src.MemberId));

cfg.CreateMap<Dto.Member, CompanyMember>()
    .ForMember(dest => CompanyMember.CompanyMemberId,
               opt => opt.MapFrom(src => src.MemberId));

Now you can map using _mapperInstance.Map<Member>(memberDto);

like image 154
whymatter Avatar answered Sep 13 '25 03:09

whymatter