Tengo una situación en la que necesito aplanar una colección de elementos.
Configuré mi perfil de mapeo así:
CreateMap<IEnumerable<IMySetting>, IMySettingLookup>() .ForMember(l => l.MySetting1, o => o.MapFrom(sc => sc.FirstOrDefault(s => s.SettingName == nameof(IMySettingLookup.MySetting1)).SettingValue)) .ForMember(l => l.MySetting2, o => o.MapFrom(sc => sc.FirstOrDefault(s => s.SettingName == nameof(IMySettingLookup.MySetting2)).SettingValue)) .As<MySettingLookup>(); // notice this is a concrete typecuando llamo a la función de mapa así:
IEnumerable<IMySetting> settings =....; IMySettingLookup lookup = _mapper.Map<IMySettingLookup>(settings);me sale este error:
AutoMapper.AutoMapperMappingException: Missing type map configuration or unsupported mapping. Mapping types: Object -> IMySettingLookup System.Object -> MyStuff.Models.IMySettingLookup Stack Trace: lambda_method(Closure , Object , IMySettingLookup, ResolutionContext )Sin embargo, cuando configuro mi perfil de mapeo usando tipos concretos y llamo al método Map con el tipo concreto como se muestra a continuación, todo funciona:
CreateMap<IEnumerable<MySetting>, MySettingLookup>() // notice everything is concrete types .ForMember(...).... and IEnumerable<MySetting> settings =....; IMySettingLookup lookup = _mapper.Map<MySettingLookup>(settings); // notice concrete types Mi pregunta es ¿cómo puedo definir mis perfiles de mapeo cuando mi tipo de fuente es IEnumerable<T> donde T es una interfaz?
EDITAR
He subido un ejemplo reproducible mínimo a https://github.com/nandun5/so-68219262-automapper
Tenga en cuenta que no veré ningún problema si simplemente uso clases concretas en lugar de las interfaces. sin embargo, esta no es realmente una opción para mí en mi escenario real porque todos mis contratos de servicio de datos son interfaces.
Parece que .As<MyType> no da el tipo concreto a usar, sino que le dice a AutoMapper qué mapeo buscar. Esto está respaldado por la documentación que establece:
Para casos simples, puede usar As para redirigir un mapa base a un mapa derivado existente :
En su caso, está buscando una asignación para IEnumerable<MySetting> to MySettingLookup , que no encuentra.
Por lo tanto, en realidad desea declarar dos asignaciones:
CreateMap<IEnumerable<IMySetting>, MySettingLookup>() .ForMember(...); CreateMap<IEnumerable<IMySetting>, IMySettingLookup>() .As<MySettingLookup>(); Esto usará la <IEnumerable<MySetting>, MySettingLookup> cuando intente asignar <IEnumerable<MySetting>, IMySettingLookup> .
Alternativamente, puede simplemente reemplazar .As<MySettingLookup>() con el siguiente .ConstructUsing(_ => new MySettingLookup()) :
CreateMap<IEnumerable<IMySetting>, IMySettingLookup>() .ForMember(...) .ConstructUsing(_ => new MySettingLookup());