Reputation: 1057
I have the following class structure from some of the layers in the app (let's call it First):
public class Participant
{
public int Id { get; set; }
public string Name { get; set; }
public virtual User User { get; set; }
public virtual Conversation Conversation { get; set; }
public virtual ICollection<Message> Messages { get; set; }
}
public class User
{
public int Id { get; set; }
public string Login { get; set; }
public virtual ICollection<Participant> Participants { get; set; }
}
public class Conversation
{
public int Id { get; set; }
public string Title { get; set; }
public virtual ICollection<Participant> Participants { get; set; }
}
Here is another layer class structure (Second):
public class Participant
{
public int Id { get; set; }
public string Name { get; set; }
public User User { get; set; }
public ICollection<Message> Messages { get; set; }
}
public class User
{
public int Id { get; set; }
public string Login { get; set; }
public ICollection<Conversation> Conversations { get; set; }
}
public class Conversation
{
public int Id { get; set; }
public string Title { get; set; }
public ICollection<Participant> Participants { get; set; }
}
They're pretty the same with the except of some details, the most important being that the User class from the second one has the direct access to the Conversations, while the User from the first one has the access only to the instances of Participant.
I have to map the instance of the First User to the Second User. Since the straightforward way of mapping doesn't work, I've decided the following algorithm might work:
When we have to map First User to Second User, take all Participants of the First User, take the Conversation of each Participant and assign it to the Second User. Each Conversation needs to be converted as well, and the Participants collection of this conversation have to be converted too. I've tried to do it without any mapping library but ran into the infinite recursion, because in order to convert First Conversation => Second Conversation, we have to convert the Participants. To convert the Participants, it's required to convert their Conversations and so on.
As far as I know, AutoMapper is capable of handling simple issues with infinite recursion; however, since my mapping is a bit more complex, AM was not able to figure out how to map classes without my help.
Unfortunately, I was not able to figure out how to implement such mapping. I've looked through this guide and I guess that's what I need but I simply cannot figure out how to write this mapping so that it will map the classes properly and not run into infinite recursion as my previous solution did.
I would be glad if someone could provide any ideas as to how to implement such mapping.
Upvotes: 1
Views: 274
Reputation: 30618
You just need to inform AutoMapper how to map the non-obvious properties, which in this case is your User class. For ease of reading, I've renamed all the classes in your "second" layer to xxxDTO.
Mapper.CreateMap<Conversation, ConversationDTO>();
Mapper.CreateMap<Participant, ParticipantDTO>();
Mapper.CreateMap<User, UserDTO>()
.ForMember(dest => dest.Conversations,opt => opt.MapFrom(src => src.Participants.Select(p => p.Conversation)));
Mapper.CreateMap<Message, MessageDTO>();
If there is the possibility that a User will be linked to a Conversation through multiple Participants, then you can include a .Distinct()
after the Select(p => p.Conversation)
.
Upvotes: 2