automapperautomapper-3

Automapper, mapping single destination property as a concatenation of multiple source property


I have a situation where I need to map a single property as a combination of multiple source properties based on some conditions.

Destination :

public class Email
{
    public Email() {
        EmailRecipient = new List<EmailRecipient>();
    }
    public string Subject{get; set;}
    public string Body {get; set;}
    public virtual ICollection<EmailRecipient> EmailRecipient { get; set; } 
}

public class EmailRecipient
{
    public int EmaiId { get; set; }
    public string RecipientEmailAddress { get; set; }
    public int RecipientEmailTypeId { get; set; }
    public virtual Email Email { get; set; }
}

Source:

public class EmailViewModel
{
    public List<EmailRecipientViewModel> To { get; set; }
    public List<EmailRecipientViewModel> Cc { get; set; }
    public string Subject { get; set; }
    public string Body { get; set; }
}

public class EmailRecipientViewModel
{
    public string RecipientEmailAddress { get; set; }
}

I want Mapper.Map<EmailViewModel,Email>()

Here I would like to map my Email.EmailRecipient as a combination of EmailViewModel.To and EmailViewModel.Cc. However the condition is, Email.EmailRecipient.RecipientEmailTypeId will be 1 for To and 2 for Cc

Hope my question is clear.


Solution

  • One possible way to achieve this is to create a map that uses a specific method for this conversion. The map creation would be:

    Mapper.CreateMap<EmailViewModel, Email>()
        .ForMember(e => e.EmailRecipient, opt => opt.MapFrom(v => JoinRecipients(v)));
    

    Where the JoinRecipients method would perform the conversion itself. A simple implementation could be something like:

    private ICollection<EmailRecipient> JoinRecipients(EmailViewModel viewModel) {
        List<EmailRecipient> result = new List<EmailRecipient>();
        foreach (var toRecipient in viewModel.To) {
            result.Add(new EmailRecipient {
                RecipientEmailTypeId = 1, 
                RecipientEmailAddress = toRecipient.RecipientEmailAddress
            });
        }
    
        foreach (var ccRecipient in viewModel.Cc) {
            result.Add(new EmailRecipient {
                RecipientEmailTypeId = 2,
                RecipientEmailAddress = ccRecipient.RecipientEmailAddress
            });
        }
    
        return result;
    }