AutoMapper: ¿"Ignorar el resto"?
¿Hay alguna manera de decirle a AutoMapper que ignore todas las propiedades excepto las que están asignadas explícitamente?
Tengo clases DTO externas que probablemente cambien desde el exterior y quiero evitar especificar que cada propiedad se ignore explícitamente, ya que agregar nuevas propiedades romperá la funcionalidad (provocará excepciones) al intentar asignarlas a mis propios objetos.
Por lo que entendí, la pregunta era que hay campos en el destino que no tienen un campo asignado en el origen, por lo que se buscan formas de ignorar esos campos de destino no asignados.
En lugar de implementar y utilizar este método de extensión, simplemente podría utilizar
Mapper.CreateMap<sourceModel, destinationModel>(MemberList.Source);
Ahora el asignador automático sabe que sólo necesita validar que todos los campos de origen estén asignados, pero no al revés.
También puedes usar:
Mapper.CreateMap<sourceModel, destinationModel>(MemberList.Destination);
Actualicé la extensión de Can Gencer para no sobrescribir ningún mapa existente.
public static IMappingExpression<TSource, TDestination>
IgnoreAllNonExisting<TSource, TDestination>(this IMappingExpression<TSource, TDestination> expression)
{
var sourceType = typeof (TSource);
var destinationType = typeof (TDestination);
var existingMaps = Mapper.GetAllTypeMaps().First(x => x.SourceType.Equals(sourceType) && x.DestinationType.Equals(destinationType));
foreach (var property in existingMaps.GetUnmappedPropertyNames())
{
expression.ForMember(property, opt => opt.Ignore());
}
return expression;
}
Uso:
Mapper.CreateMap<SourceType, DestinationType>()
.ForMember(prop => x.Property, opt => opt.MapFrom(src => src.OtherProperty))
.IgnoreAllNonExisting();
ACTUALIZACIÓN: Tenga en cuenta que en la versión 9.0 se eliminó la API estática de Mapper
Actualización: esta respuesta ya no es útil para quienes usan versiones actualizadas de Automapper, ya que ForAllOtherMembers
se eliminó en Automapper 11 .
La versión 5.0.0-beta-1 de AutoMapper introduce el ForAllOtherMembers
método de extensión para que ahora puedas hacer esto:
CreateMap<Source, Destination>()
.ForMember(d => d.Text, o => o.MapFrom(s => s.Name))
.ForMember(d => d.Value, o => o.MapFrom(s => s.Id))
.ForAllOtherMembers(opts => opts.Ignore());
Tenga en cuenta que existe una ventaja al mapear explícitamente cada propiedad, ya que nunca tendrá problemas de falla silenciosa en el mapeo que surgen cuando se olvida mapear una propiedad.
Quizás en su caso sería prudente ignorar a todos los demás miembros y agregar un TODO
para volver y hacerlos explícitos después de que se estabilice la frecuencia de los cambios en esta clase.