2010-02-10 19 views

Respuesta

113

Uso ConstructUsing

esto permitirá que se especifique el constructor para su uso durante el mapeo. pero luego todas las otras propiedades se mapearán automáticamente de acuerdo con las convenciones.

También tenga en cuenta que esto es diferente de ConvertUsing en que el uso de conversión no seguirá mapeando a través de las convenciones, sino que le dará un control total de la asignación.

Mapper.CreateMap<ObjectFrom, ObjectTo>() 
    .ConstructUsing(x => new ObjectTo(arg0, arg1, etc)); 

...

using AutoMapper; 
using NUnit.Framework; 

namespace UnitTests 
{ 
    [TestFixture] 
    public class Tester 
    { 
     [Test] 
     public void Test_ConstructUsing() 
     { 
      Mapper.CreateMap<ObjectFrom, ObjectTo>() 
       .ConstructUsing(x => new ObjectTo(x.Name)); 

      var from = new ObjectFrom { Name = "Jon", Age = 25 }; 

      ObjectTo to = Mapper.Map<ObjectFrom, ObjectTo>(from); 

      Assert.That(to.Name, Is.EqualTo(from.Name)); 
      Assert.That(to.Age, Is.EqualTo(from.Age)); 
     } 
    } 

    public class ObjectFrom 
    { 
     public string Name { get; set; } 
     public int Age { get; set; } 
    } 

    public class ObjectTo 
    { 
     private readonly string _name; 

     public ObjectTo(string name) 
     { 
      _name = name; 
     } 

     public string Name 
     { 
      get { return _name; } 
     } 

     public int Age { get; set; } 
    } 
} 
+0

Supongo que "ConstructUsing" debe estar en una versión más nueva de automapper que la w estamos usando. Gracias Jon – jlembke

+6

Muchas gracias por este ejemplo Jon. "ConstructUsing" es genial! Me permite mantener mis DTO inmutables con setters marcados como privados. – Daniel

+3

Funciona como un regalo para mí; Actualmente, AutoMapper no le gusta los constructores donde todos los parámetros son opcionales, así que solo uso .ConstructUsing (x => new MyClass()); –

7

Debe utilizar el método Map que le permite establecer el destino. Por ejemplo:

Mapper.CreateMap<ObjectFrom, ObjectTo>() 

var from = new ObjectFrom { Name = "Jon", Age = 25 }; 

var to = Mapper.Map(from, new ObjectTo(param1)); 
0

En el momento de escribir esta respuesta, AutoMapper lo hará automáticamente (con una simple llamada CreateMap<>()) para usted si las propiedades se ajustan a los parámetros del constructor. Por supuesto, si las cosas no coinciden, usar .ConstructUsing(...) es el camino a seguir.

public class PersonViewModel 
{ 
    public int Id { get; set; } 

    public string Name { get; set; } 
} 

public class Person 
{ 
    public Person (int id, string name) 
    { 
     Id = id; 
     Name = name; 
    } 

    public int Id { get; } 

    public string Name { get; } 
} 

public class PersonProfile : Profile 
{ 
    public PersonProfile() 
    { 
     CreateMap<PersonProfile, Person>(); 
    } 
} 

Nota: Esto asume que está utilizando Profiles para configurar sus asignaciones AutoMapper.

Cuando se utiliza como el de abajo, esto produce el objeto correcto:

var model = new PersonModel 
{ 
    Id = 1 
    Name = "John Smith" 
} 

// will correctly call the (id, name) constructor of Person 
_mapper.Map<Person>(model); 

Usted puede leer más sobre la construcción AutoMapper en el oficial wiki on GitHub

2

La mejor práctica es utilizar enfoques documentados de AutoMapper https://github.com/AutoMapper/AutoMapper/wiki/Construction

public class SourceDto 
{ 
     public SourceDto(int valueParamSomeOtherName) 
     { 
      Value = valueParamSomeOtherName; 
     } 

     public int Value { get; } 
} 

Mapper.Initialize(cfg => cfg.CreateMap<Source, SourceDto>().ForCtorParam("valueParamSomeOtherName", opt => opt.MapFrom(src => src.Value))); 
Cuestiones relacionadas