En los casos en que mis establecedores de destino son privados, me gustaría asignar al objeto utilizando el constructor del objeto de destino. ¿Cómo harías esto usando Automapper?Automapper: cómo asignar a los parámetros del constructor en lugar de los generadores de propiedades
Automapper: cómo asignar a los parámetros del constructor en lugar de los generadores de propiedades
Respuesta
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; }
}
}
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));
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
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)));
- 1. Parámetros de asInncTask doInBackground frente a los parámetros del constructor
- 2. copiar los parámetros del constructor
- 3. ¿Asignar los parámetros de URI a las propiedades del objeto de parámetro?
- 4. Asignación de algunas propiedades en lugar de todas usando Automapper
- 5. Uso de Automapper cuando los nombres de propiedades son diferentes
- 6. Pasar hashes en lugar de los parámetros del método
- 7. Agregar elementos a los generadores de pitón
- 8. Castle Windsor que pasa los parámetros del constructor
- 9. Castle Windsor IOC: paso de los parámetros del constructor a los componentes secundarios
- 10. Castillo de Windsor - cómo resolver los componentes en base a parámetros del constructor
- 11. Convierte los carriles de 2 generadores a los rieles 3?
- 12. Propiedades nulo de Automapper
- 13. AutoMapper y es * propiedades especificadas
- 14. C# Vincular los parámetros del constructor a las variables de instancia
- 15. Usando Guice, ¿cómo puedo inyectar los parámetros del constructor de la superclase?
- 16. constructor uml classdiagram con los parámetros
- 17. Cómo administrar propiedades personalizadas en AutoMapper
- 18. Descripción de los generadores en Python
- 19. AutoMapper utilizando el constructor incorrecto
- 20. AutoMapper TypeConverter constructor personalizado
- 21. ¿Cómo asignar una cadena a una fecha en Automapper?
- 22. ¿Cómo puede obtener los nombres de los parámetros del método?
- 23. Cómo hacer que los generadores llamen a otros generadores en rieles 3
- 24. Iterar a través de los parámetros del método
- 25. ¿Cómo asignar los parámetros de Fecha a Hibernar consulta para la zona horaria actual?
- 26. ¿Por qué no podemos llamar al constructor servlet en lugar del método init para inicializar los parámetros de configuración?
- 27. Cómo obtener el constructor predeterminado cuando los parámetros son opcionales
- 28. ¿Cuál es la forma preferida de construir objetos en C#? ¿Parámetros o propiedades del constructor?
- 29. AutoMapper: Asignar un Enum a su [Descripción] atribuir
- 30. Recuperar parámetros del archivo de propiedades
Supongo que "ConstructUsing" debe estar en una versión más nueva de automapper que la w estamos usando. Gracias Jon – jlembke
Muchas gracias por este ejemplo Jon. "ConstructUsing" es genial! Me permite mantener mis DTO inmutables con setters marcados como privados. – Daniel
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()); –