At the time of writing this answer, AutoMapper will do this automatically (with a simple CreateMap<>() call) for you if the properties match the constructor parameters.
If you want some of the properties not to map with the destination type property then you need to use the AutoMapper Ignore Property in C#. Note: If some of the properties are not available in the destination type, then the AutoMapper will not throw any exception when doing the mapping.
Yes, or you can call CreateMap<ModelClass, ViewModelClass>(). ReverseMap() .
AutoMapper will map property with private setter with no problem. If you want to force encapsulation, you need to use IgnoreAllPropertiesWithAnInaccessibleSetter. With this option, all private properties (and other inaccessible) will be ignored.
Use ConstructUsing
this will allow you to specify which constructor to use during the mapping. but then all of the other properties will be automatically mapped according to the conventions.
Also note that this is different from ConvertUsing
in that convert using will not continue to map via the conventions, it will instead give you full control of the mapping.
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; }
}
}
The best practice is to use documented approaches from AutoMapper http://docs.automapper.org/en/stable/Construction.html
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)
)
);
You should use the Map
method that lets you set the destination. For example :
Mapper.CreateMap<ObjectFrom, ObjectTo>()
var from = new ObjectFrom { Name = "Jon", Age = 25 };
var to = Mapper.Map(from, new ObjectTo(param1));
At the time of writing this answer, AutoMapper will do this automatically (with a simple CreateMap<>()
call) for you if the properties match the constructor parameters. Of course, if things don't match up, then using .ConstructUsing(...)
is the way to go.
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<PersonViewModel, Person>();
}
}
Note: This assumes you are using Profiles to setup your automapper mappings.
When used like below, this produces the correct object:
var model = new PersonViewModel
{
Id = 1
Name = "John Smith"
}
// will correctly call the (id, name) constructor of Person
_mapper.Map<Person>(model);
You can read more about automapper construction in the offical wiki on GitHub
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With