Automapper - как отобразить параметры конструктора вместо установщиков свойств - PullRequest
95 голосов
/ 10 февраля 2010

В тех случаях, когда мои установщики назначения являются частными, я мог бы хотеть сопоставить объекту, используя конструктор объекта назначения. Как бы вы сделали это с помощью Automapper?

Ответы [ 4 ]

138 голосов
/ 10 февраля 2010

Использование ConstructUsing

это позволит вам указать, какой конструктор использовать во время отображения. но тогда все остальные свойства будут автоматически сопоставлены в соответствии с соглашениями.

Также обратите внимание, что это отличается от ConvertUsing тем, что преобразование с использованием не будет продолжать отображаться через соглашения, вместо этого оно даст вам полный контроль над отображением.

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; }
    }
}
9 голосов
/ 28 февраля 2014

Вы должны использовать метод Map, который позволяет вам установить пункт назначения. Например:

Mapper.CreateMap<ObjectFrom, ObjectTo>()

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

var to = Mapper.Map(from, new ObjectTo(param1));
6 голосов
/ 06 августа 2017

Лучшая практика - использовать документированные подходы от 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)));
0 голосов
/ 04 мая 2017

Во время написания этого ответа AutoMapper сделает это автоматически (с простым вызовом CreateMap<>()), если свойства соответствуют параметрам конструктора. Конечно, если что-то не совпадает, тогда стоит использовать .ConstructUsing(...).

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>();
    }
}

Примечание. Предполагается, что вы используете Профили для настройки сопоставлений ваших автоматов.

При использовании, как показано ниже, получается правильный объект:

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

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

Вы можете узнать больше о конструкции автоматического автомата в официальном вики на GitHub

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...