使用AutoMapper是否可以将属性指定为私有的setter?
使用AutoMapper是否可以将属性指定为私有的setter?
AutoMapper现在允许(我不确定是从何时开始)映射具有私有setter的属性。它使用反射来创建对象。
示例类:
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可以轻松地映射具有私有setter的属性。如果你想强制封装,你需要使用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中,您无法使用反射来访问私有类型和成员。
private set
可以被移除。但是当我这样做时,AutoMapper无法再映射该属性。它不会报错,只是将私有属性设置为其初始值! - comecme[UsedImplicitly]
属性装饰此类属性。这告诉 ReSharper 某些内容是通过反射或其他框架行为间接使用的。 - Logarr如果您像这样在构造函数中设置此属性的值
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);
public class PrivateInternalProfile {
protected override Configure() {
ShouldMapField = fieldInfo => true;
ShouldMapProperty = propertyInfo => true;
CreateMap<User, UserDto>(); //etc
}
}