0

I have a table Message:

CREATE TABLE [Communication].[Message]
(
    [MessageID] BIGINT NOT NULL PRIMARY KEY IDENTITY, 
    [MessageChannelID] INT NOT NULL,
    [MessageStatusID] INT NOT NULL, 
    [Sender] NVARCHAR(100) NOT NULL, 
    [SenderDisplayName] NVARCHAR(100) NULL, 
    [Receiver] NVARCHAR(100) NOT NULL, 
    [Content] NVARCHAR(MAX) NULL, 
    [EmailUseSSL] BIT NOT NULL DEFAULT 0, 
    [EmailReceiverCC] NVARCHAR(100) NULL, 
    [EmailReceiverBCC] NVARCHAR(100) NULL, 
    [EmailSenderReplyTo] NVARCHAR(100) NULL, 
    [EmailSubject] NVARCHAR(300) NULL, 
    [SMSGUID] NVARCHAR(100) NULL, 
    [CreatedAt] DATETIME NOT NULL DEFAULT getDate(), 
    [Note] NVARCHAR(300) NULL, 
    CONSTRAINT [FK_Message_MessageStatus] FOREIGN KEY ([MessageStatusID]) REFERENCES [Communication].[MessageStatus]([MessageStatusID]), 
    CONSTRAINT [FK_Message_MessageChannel] FOREIGN KEY ([MessageChannelID]) REFERENCES [Communication].[MessageChannel]([MessageChannelID])
)

And I have DTO classes:

public class MessageDTO
{
    public int MessageID { get; set; }
    public string Sender { get; set; }
    public string SenderDisplayName { get; set; }
    public string Receiver { get; set; }
    public string Content { get; set; }
    public DateTime CreatedAt { get; internal set; }
    public string Note { get; set; }
    public MessageStatus Status { get; set; }
    public MessageChannel Channel { get; internal set; }
}

public class EmailMessageDTO: MessageDTO
{
    public bool EmailUseSSL { get; set; }
    public string EmailReceiverCC { get; set; }
    public string EmailReceiverBCC { get; set; }
    public string EmailSenderReplyTo { get; set; }
    public string EmailSubject { get; set; }
}

public class SMSMessageDTO: MessageDTO
{
    public string SMSGUID { get; set; }
}

Message type can be resolved from MessageChannelID (Email, SMS). Is it possible to use Automapper to get all messages with specific status, so that some messages are mapped to EmailMessageDTO and others to SMSMessageDTO? I want to write a GetMessages method that returns all messages, with objects EmailMessageDTO or SMSMessageDTO, according to message type.

vpetrovic
  • 527
  • 4
  • 22
  • Have you tried something like: http://stackoverflow.com/questions/9746650/automapper-conditional-mapping-for-type - essentially using the `ConstructUsing` function and mapping to the base type - any mappings will have their instances created via `ConstructUsing`. The only issue may be that specific mapping options may not be possible, I'm not sure if AutoMapper will realise it's no longer a `dto -> base` mapping and use a more specific mapping configuration. – Charleh Apr 24 '17 at 12:14
  • I saw that solution, it helped me to solve this! – vpetrovic Apr 24 '17 at 12:56

1 Answers1

1

After Charleh's comment, I came up with this:

x.CreateMap<Message, MessageDTO>()
                    .ForMember(m => m.Status, opts => opts.MapFrom(src => src.MessageStatusID))
                    .ForMember(m => m.Channel, opts => opts.MapFrom(src => src.MessageChannelID))
                    .ConstructUsing(m =>
                    {
                        if (m.MessageChannelID == (int)Data.MessageChannel.Email)
                            return new EmailMessageDTO
                            {
                                EmailReceiverBCC = m.EmailReceiverBCC,
                                EmailReceiverCC = m.EmailReceiverCC,
                                EmailSenderReplyTo = m.EmailSenderReplyTo,
                                EmailSubject = m.EmailSubject,
                                EmailUseSSL = m.EmailUseSSL
                            };
                        else return new SMSMessageDTO
                        {
                            SMSGUID = m.SMSGUID
                        };
                    });
vpetrovic
  • 527
  • 4
  • 22
  • Cool, it's still a little manual but at least it's contained within the mapping configuration so you don't have to think about it :) – Charleh Apr 24 '17 at 16:12