Automapper - cómo asignar a parámetros de constructor en lugar de setters de propiedad


En los casos en los que mis setters de destino son privados, es posible que desee asignar al objeto usando el constructor del objeto de destino. ¿Cómo harías esto usando Automapper?

 87
Author: jlembke, 2010-02-10

4 answers

Use ConstructUsing

Esto le permitirá especificar qué constructor usar durante la asignación. pero luego todas las otras propiedades se asignarán automáticamente de acuerdo con las convenciones.

También tenga en cuenta que esto es diferente de ConvertUsing en que convert using no continuará mapeando a través de las convenciones, sino que le dará el 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; }
    }
}
 124
Author: Jon Erickson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-06-21 05:35:59

Debe usar 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));
 7
Author: Matthieu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-02-28 19:22:01

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)));
 3
Author: Anton Shcherbyna,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-08-06 17:09:27

En el momento de escribir esta respuesta, AutoMapper hará esto automáticamente (con una simple llamada CreateMap<>()) para usted si las propiedades coinciden con los parámetros del constructor. Por supuesto, si las cosas no coinciden, entonces 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 supone que está utilizando Profiles para configurar sus asignaciones de automapper.

Cuando se usa como 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);

Puede leer más sobre la construcción de automapper en la oficina wiki en GitHub

 0
Author: lxalln,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-04 14:39:49