net formember custom c# .net mapping automapper

c# - formember - automapper net core



¿Cómo usar mapper.Map dentro de MapperConfiguration de AutoMapper? (2)

Necesito asignar un objeto a otro usando AutoMapper. La pregunta difícil es ¿cómo puedo acceder a una instancia del asignador (instancia de IMapper) dentro de la configuración de mapeo o dentro de un convertidor de tipo personalizado?

El código a continuación no funciona, sin embargo, es un ejemplo de lo que me gustaría lograr. Observe el mapper.Map un mapper.Map llamadas y suponga que se definen las asignaciones Customer => CustomerDto y Customer => DetailedCustomerDto .

var config = new MapperConfiguration( cfg => cfg.CreateMap<Order, OrderDto>() .ForMember(dst => dst.Customer, src => src.ResolveUsing(o => { return o.Type == 1 ? mapper.Map<Customer, CustomerDto>(o.Customer) : mapper.Map<Customer, DetailedCustomerDto>(o.Customer) }) );

La parte del cliente es:

var mapper = config.CreateMapper(); var orderDto = mapper.Map<Order, OrderDto>(order);

La versión simplificada de los objetos que quiero asignar es:

public class Order { public int Type { get; set; } public Customer Customer { get; set; } } public class Customer { public long Id { get; set; } public string Name { get; set; } } public class OrderDto { public CustomerDto Customer { get; set; } } public class CustomerDto { public long Id { get; set; } } public class DetailedCustomerDto : CustomerDto { public string Name { get; set; } }

Como se ve en los códigos anteriores, según el valor de Order.Type , el asignador debe asignar la propiedad Order.Customer a diferentes objetivos. Como un objetivo ( DetailedCustomerDto ) se hereda del otro ( CustomerDto ), se vuelve un poco complicado.

Tenga en cuenta que el uso del método estático obsoleto y en desuso Mapper.Map NO es una opción .


Además de la gran respuesta de Evk, que me ayudó, si necesita realizar un mapeo dentro de un mapeo dentro de una configuración / perfil que requiere un constructor personalizado (es decir, el tipo no tiene un constructor predeterminado), lo siguiente funcionará en v5.2.0:

CreateMap<Models.Job, Models.API.Job>(MemberList.Source); CreateMap<StaticPagedList<Models.Job>, StaticPagedList<Models.API.Job>>() .ConstructUsing((source, context) => new StaticPagedList<Models.API.Job>( context.Mapper.Map<List<Models.Job>, List<Models.API.Job>>(source.ToList()), source.PageNumber, source.PageSize, source.TotalItemCount));

En este ejemplo, estoy asignando el tipo de colección personalizada X.PagedList de un tipo de objeto a una colección equivalente de otro tipo de objeto. El primer parámetro de la expresión lamdba es su objeto de origen, el segundo es su ResolutionContext desde el cual puede acceder a una instancia del asignador desde la que asignar.


A partir de AutoMapper 5.1.1

Puede llegar al asignador usando otra sobrecarga de ResolveUsing con cuatro parámetros, el cuarto de los cuales es ResolutionContext ( context.Mapper ):

var config = new MapperConfiguration( cfg => { cfg.CreateMap<Customer, CustomerDto>(); cfg.CreateMap<Customer, DetailedCustomerDto>(); cfg.CreateMap<Order, OrderDto>() .ForMember(dst => dst.Customer, src => src.ResolveUsing((order, orderDto, i, context) => { return order.Type == 1 ? context.Mapper.Map<Customer, CustomerDto>(order.Customer) : context.Mapper.Map<Customer, DetailedCustomerDto>(order.Customer); })); }); var orderTypeOne = new Order(); orderTypeOne.Type = 1; orderTypeOne.Customer = new Customer() { Id = 1 }; var dto = config.CreateMapper().Map<Order, OrderDto>(orderTypeOne); Debug.Assert(dto.Customer.GetType() == typeof (CustomerDto)); var orderTypeTwo = new Order(); orderTypeTwo.Type = 2; orderTypeTwo.Customer = new Customer() { Id = 1 }; dto = config.CreateMapper().Map<Order, OrderDto>(orderTypeTwo); Debug.Assert(dto.Customer.GetType() == typeof (DetailedCustomerDto));

Antes de AutoMapper 5.1.1

Puede llegar al asignador utilizando otra sobrecarga de ResolveUsing con dos parámetros, el primero de los cuales es ResolutionResult ( result.Context.Engine.Mapper ):

var config = new MapperConfiguration( cfg => { cfg.CreateMap<Customer, CustomerDto>(); cfg.CreateMap<Customer, DetailedCustomerDto>(); cfg.CreateMap<Order, OrderDto>() .ForMember(dst => dst.Customer, src => src.ResolveUsing((result, order) => { return order.Type == 1 ? result.Context.Engine.Mapper.Map<Customer, CustomerDto>(order.Customer) : result.Context.Engine.Mapper.Map<Customer, DetailedCustomerDto>(order.Customer); })); }); var orderTypeOne = new Order(); orderTypeOne.Type = 1; orderTypeOne.Customer = new Customer() { Id = 1 }; var dto = config.CreateMapper().Map<Order, OrderDto>(orderTypeOne); Debug.Assert(dto.Customer.GetType() == typeof (CustomerDto)); var orderTypeTwo = new Order(); orderTypeTwo.Type = 2; orderTypeTwo.Customer = new Customer() { Id = 1 }; dto = config.CreateMapper().Map<Order, OrderDto>(orderTypeTwo); Debug.Assert(dto.Customer.GetType() == typeof (DetailedCustomerDto));