简体   繁体   中英

Automapper convention based mapping for collection

I have a project where I am trying to map a dictionary to a ViewModel.NamedProperty. I am trying to use an AutoMapper custom resolver to perform the mapping based on a convention. My convention is that if the named property exists for the source dictionary key then map a property from the dictionary's value. Here are my example classes:

class User
{
   string Name {get;set;}
   Dictionary<string, AccountProp> CustomProperties {get;set;}
}

class AccountProp
{
   string PropertyValue {get;set;}
   //Some other properties

}

class UserViewModel
{
   string Name {get;set;}
   DateTime LastLogin {get;set;}
   string City {get;set}
}

var user = new User()
{
   Name = "Bob"   
};

user.CustomProperties.Add("LastLogin", new AccountProp(){PropertyValue = DateTime.Now};
user.CustomProperties.Add("City", new AccountProp(){PropertyValue = "SomeWhere"};

I want to map the User CustomProperties dictionary to the flattened UserViewModel by convention for all properties and I do not want to specify each property individually for the mapping.

What is the best way to go about this? I was thinking Custom value resolver but it seems that I have to specify each member I want to map individually. If I wanted to do that I would just manually perform the mapping without AutoMapper.

Below is code that serve the purpose. Not sure whether it is good or not.

Mapper.CreateMap<User, UserViewModel>()
    .ForMember(dest => dest.Name, opt => opt.MapFrom(src => src.Name))                // Optional
    .ForMember(dest => dest.City, opt => opt.MapFrom(src => src.CustomProperties.FirstOrDefault(x => x.Key == "City").Value.PropertyValue.ToString()))  // Handle null
    .ForMember(dest => dest.LastLogin, opt => opt.MapFrom(src => Convert.ToDateTime(src.CustomProperties.FirstOrDefault(x => x.Key == "LastLogin").Value.PropertyValue)));  //Handle null

I ended up creating a custom type converter to deal with this scenario and it works great:

public class ObjectToPropertyTypeConverter<TFromEntity> : ITypeConverter<TFromEntity, HashSet<Property>>
{
 //perform custom conversion here
}

I then implemented the Custom mapping as follows:

 AutoMapper.Mapper.CreateMap<MyViewModel, HashSet<Property>>()
               .ConvertUsing<ObjectToPropertyTypeConverter<MyViewModel>>();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM