Search code examples
.netautomapper

Access IMappingOperationOptions dictionary in .ForMember() without IValueResolver


I'm trying to map two objects and the destination has data that require additional data sources. These are the classes:

public class SourceClass {
  public int SrcValueOne { get; set; }
}

public class DestClass { 
  public int DestValueOne { get; set; }

  public int ValueFromConfig { get; set; }
}

public class ConfigSettings { 
  public int ConfigValueOne { get; set; }
}

I need to map values in the SourceClass to DestClass and, at the same time, pass a populated ConfigSettings object (at runtime) to the Map() and read some values from there. Thus far all I've found is a ResolveUsing method which doesn't seem ideal. I'm wondering if there's a way to do something similar to this:

Mapper.CreateMap<SourceClass, DestClass>()
  .ForMember(dest => dest.DestValueOne, src => src.MapFrom(a => a.SrcValueOne))
  .ForMember(dest => dest.ValueFromConfig, src => opt.ResolveUsing<ConfigSettings>.FromMember(config => config.ConfigValueOne);

I figured out how to pass the populated object at runtime in the Map() using the Items collection, but can't figure out if there's a way to access it in the ResolveUsing without creating Resolvers and/or using reflection.


Solution

  • Mapper.CreateMap<ConfigSettings, DestCLass>()
       .ForMember(dest => dest.ValueFromConfig, opt => opt.MapFrom(s => s.ConfigValueOne))
       .ForMember(dest => dest.DestValueOne, opt => opt.Ignore());
    Mapper.CreateMap<SourceClass, DestClass>()
      .ForMember(dest => dest.DestValueOne, opt => opt.MapFrom(a => a.SrcValueOne))
      .ForMember(dest => dest.ValueFromConfig, opt => opt.Ignore());
    
    var dest = Mapper.Map(config);
    Mapper.Map(source, dest);
    

    This is the simplest option you have if you don't want to introduce another class.

    Adding a new class can help to encapsulate this to only one Map call:

    public class ComplexSource
    {
        public ConfigSettings Config{get;set;}
        public SourceClass SourceData{get;set;}
    }
    
    Mapper.CreateMap<ComplexSource, DestClass>()....