2011-04-28 12 views
9

Dados los siguientes tipos de fuentes:Automapper resuelve automáticamente la subclase correcta para mapear?

public class BaseViewModel 
{ 
    public string Prop1 { get; set; } 
} 

public class FirstViewModelImpl : BaseViewModel 
{ 
    public string Prop2 { get; set; } 
} 

public class SecondViewModelImpl : BaseViewModel 
{ 
    public string AnotherProp { get; set; } 
} 

y los siguientes tipos de destino

public class BaseDto 
{ 
    public string Prop1 { get; set; } 
} 

public class FirstDtoImpl : BaseDto 
{ 
    public string Prop2 { get; set; } 
} 

public class SecondDtoImpl : BaseViewModel 
{ 
    public string AnotherProp { get; set; } 
} 

Con las siguientes asignaciones:

Mapper.CreateMap<FirstViewModelImpl,FirstDtoImpl>(); 
Mapper.CreateMap<SecondViewModelImpl,SecondDtoImpl>(); 

¿Puedo hacer lo siguiente (ejemplo trivial) - dado que realmente no conozco el tipo de viewmodel hasta el tiempo de ejecución?

BaseViewModel myViewModel = GetAViewModelFromSomewhere(); 
FirstDtoImpl dto = (FirstDtoImpl)Mapper.Map<BaseViewModel,BaseDto>(myViewModel); 

¡Estoy intentando esto ahora de todos modos!

+0

Right Acabo de probar esto y parece que no es posible, a menos que me falta algo? –

Respuesta

18

He encontrado que si cambio de las asignaciones a

Mapper.CreateMap<BaseViewModel,BaseDto>() 
     .Include<FirstViewModelImpl,FirstDtoImpl>() 
     .Include<SecondViewModelImpl,SecondDtoImpl>(); 

Mapper.CreateMap<FirstViewModelImpl,FirstDtoImpl>(); 
Mapper.CreateMap<SecondViewModelImpl,SecondDtoImpl>(); 

entonces funciona como se esperaba sin utilizar el convertidor de tipos.

+0

Oh mi, me gusta eso. – Rangoric

1

¿Se puede usar una interfaz? Además, existe una implementación de Mapper.Map no genérica que podría funcionar mejor en este caso. Si tiene configurada la asignación, puede pasar el tipo.

+0

No estoy seguro de que una interfaz ayude y la no genérica todavía requiere que conozca el tipo concreto. –

+0

¿No podría pasar en typeof (obj) como parámetro? Seguramente puedes resolver el tipo de alguna manera. –

+0

Tendré un juego con typeof gracias. –

0

No, esto no es correcto si crea Mapeo de tipos derivados que debe cuando objetos del mapa especificar la clase derivada también

3

Usted no puede hacerlo directamente, sin embargo se puede evitar con un TypeConverter.

En las asignaciones va a agregar:

Mapper.CreateMap<BaseViewModel, BaseDto>() 
    .ConvertUsing<MyTypeConverter>(); 

continuación, puede crear el convertidor de este modo:

public class MyTypeConverter : TypeConverter<BaseViewModel, BaseDto> 
{ 
    protected override BaseDto ConvertCore(BaseViewModel tViewModel) 
    { 
     BaseDto vResult = null; 
     if(tViewModel is FirstViewModelImpl) 
     { 
      var vSource = tViewModel as FirstViewModelImpl; 
      vResult = Mapper.Map<FirstViewModelImpl,FirstDtoImpl>(vSource); 
     } 
     else if(tViewModel is SecondViewModelImpl) 
     { 
      var vSource = tViewModel as SecondViewModelImpl ; 
      vResult = Mapper.Map<SecondViewModelImpl ,SecondDtoImpl>(vSource); 
     } 
     return vResult; 
    } 
} 

A continuación, puede usarla como:

BaseDto dto= Mapper.Map<BaseViewModel,BaseDto>(myViewModel); 

y tienen dto realmente es del tipo que quería.

Sin embargo, no correlacionará los tipos de Base entre sí. Si eso importa, puedo girarlo un poco más.

+0

Parece prometedor. Los tipos de base no importan, son abstractos en mi código real. –

Cuestiones relacionadas