Можно ли назначать свойства с помощью private seters с помощью AutoMapper?
Свойства сопоставления AutoMapper с частными сеттерами
Ответ 1
Если вы установите значение для этих свойств в конструкторе, например,
public class RestrictedName
{
public RestrictedName(string name)
{
Name = name;
}
public string Name { get; private set; }
}
public class OpenName
{
public string Name { get; set; }
}
то вы можете использовать ConstructUsing, как это
Mapper.CreateMap<OpenName, RestrictedName>()
.ConstructUsing(s => new RestrictedName(s.Name));
который работает с этим кодом
var openName = new OpenName {Name = "a"};
var restrictedName = Mapper.Map<OpenName, RestrictedName>(openName);
Assert.AreEqual(openName.Name, restrictedName.Name);
Ответ 2
AutoMapper позволяет теперь (я не уверен, с каких пор) сопоставлять свойства с частными установщиками. Он использует отражение для создания объектов.
Примеры классов:
public class Person
{
public string Name { get; set; }
public string Surname { get; set; }
}
public class PersonDto
{
public string Fullname { get; private set; }
}
И отображение:
AutoMapper.Mapper.CreateMap<Person, PersonDto>()
.ForMember(dest => dest.Fullname, conf => conf.MapFrom(src => src.Name + " " + src.Surname));
var p = new Person()
{
Name = "John",
Surname = "Doe"
};
var pDto = AutoMapper.Mapper.Map<PersonDto>(p);
AutoMapper сопоставит свойство с частным установщиком без проблем. Если вы хотите принудительно инкапсулировать, вам нужно использовать IgnoreAllPropertiesWithAnInaccessibleSetter. С помощью этой опции все частные свойства (и другие недоступные) будут игнорироваться.
AutoMapper.Mapper.CreateMap<Person, PersonDto>()
.ForMember(dest => dest.Fullname, conf => conf.MapFrom(src => src.Name + " " + src.Surname))
.IgnoreAllPropertiesWithAnInaccessibleSetter();
Проблема возникнет, если вы будете использовать Silverlight. По данным MSDN: https://msdn.microsoft.com/en-us/library/stfy7tfc(v=VS.95).aspx
В Silverlight нельзя использовать отражение для доступа к закрытым типам и членам.
Ответ 3
См. # 600 Свойства частного/внутреннего назначения.
Решение:
public class PrivateInternalProfile {
protected override Configure() {
ShouldMapField = fieldInfo => true;
ShouldMapProperty = propertyInfo => true;
CreateMap<User, UserDto>(); //etc
}
}