Automapper – 如何映射到构造函数参数而不是属性设置器
在我的目标设置器是私有的情况下,我可能想要使用目标对象的构造器映射到对象。 你将如何使用Automapper来做到这一点?
使用ConstructUsing
这将允许您指定在映射期间使用哪个构造函数。 但是所有其他的属性将会按照惯例自动映射。
还要注意,这与ConvertUsing
不同, 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; } } }
你应该使用Map
方法来设置目标。 例如 :
Mapper.CreateMap<ObjectFrom, ObjectTo>() var from = new ObjectFrom { Name = "Jon", Age = 25 }; var to = Mapper.Map(from, new ObjectTo(param1));
最好的做法是使用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)));
在编写这个答案时,如果属性匹配构造函数参数,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>(); } }
注意:这假定您正在使用configuration文件来设置您的自动映射器映射。
当像下面一样使用时,这会产生正确的对象:
var model = new PersonModel { Id = 1 Name = "John Smith" } // will correctly call the (id, name) constructor of Person _mapper.Map<Person>(model);
你可以在GitHub的官方wiki上阅读更多关于automapper构造的知识