简体   繁体   中英

Map Nested object to a custom object in C# using a mapping library

I have the following object structure :

/// <summary>
/// nested message instance provided by a business service
/// </summary>
public class Message
{
    public string Subject { get; set; }
    public DateTime CreationDate { get; set; }
    public List<Message> Messages { get; set; }
}

and I want to map that object to the following object structure :

/// <summary>
/// UI Object used to display a nested message structure
/// </summary>
public class MessageViewModel : ViewModelBase
{
    public bool IsSelected { get; set; }

    public string Subject { get; set; }

    public DateTime CreationDate { get; set; }
    public List<MessageViewModel> Messages { get; set; }
}

Is there any mapper that can get the job done easily ?

You can use AutoMapper for this. To map some types first you need to create some mappings:

Mapper.Initialize(cfg => cfg
    .CreateMap<Message, MessageViewModel>());

This creates a mapping from Message to MessageViewModel . By default AutoMapper maps all the properties with the same name. Nested complex properties will also be mapped when there are mappings for their types specified. So in your example the above mapping is enough because nested property type is the same as its parent type and each property of a source type has its corresponding property with the same name in a target type. Collections are mapped to other collections implicitly.

To map a concrete object you can use Mapper.Map method:

var messageViewModel = Mapper.Map<MessageViewModel>(message);

This is only example for a static mapper but there is also a possibility to create mapper as an object. For more advanced topics you can read the docs: http://docs.automapper.org/en/stable/

I would strongly recommend using Automapper as its very simple and easy to use. In Automapper, fields having the same name get mapped by default and require minimal configuration. The mapping you want to achieve would be done as follows:

  var config = new MapperConfiguration(cfg =>
  {
      cfg.CreateMap<Message, MessageViewModel>();
  });

In case of collections, Automapper can map the following, provided a configuration has been defined for their data types:

  • IEnumerable
  • ICollection
  • IList
  • List
  • Arrays

Since a mapping is already provided for the data types of the Lists in your case, further configuration will not be needed.

In case you want to map fields with different names or you want some basic level validation in the process, you can use the following syntax to define a configuration:

var config = new MapperConfiguration(cfg =>
{
    cfg.CreateMap<Message, MessageViewModel>()
    .ForMember(destination => destination.SomeDestinationField, map => map.MapFrom(source => source.SomeSourceFieldWithDifferentName))
    .ForMember(destination => destination.SomeDestinationField, map => map.MapFrom(source => source.SomeSourceField ?? SomeDefaultValue));
});

We can then use a MapperConfiguration object to initialize a Mapper and perform our mappings as follows:

SourceClass SourceObject = new SourceClass();
// Populate SourceObject with values

var mapper = config.CreateMapper();
DesitnationClass DestinationObject = mapper.Map<DesitnationClass>(SourceObject);

I would recommend going through these docs .

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