返回总目录
首先,先创建一个控制台项目,引用AutoMapper程序集,创建三个类User,UserDto,UserMappingPRofile,下面的知识点的演示都以此项目为基础,代码分别如下:
namespace MiddleAutoMapper{ public class User { public User() { } public int Age { get; set; } }}
namespace MiddleAutoMapper{ public class UserDto { public UserDto(int age) { this.age = age; } private int age; public int Age { get { return age; } } }}
namespace MiddleAutoMapper{ public class UserMappingProfile:Profile { protected override void Configure() { //添加配置方法 } }}
namespace MiddleAutoMapper{ class Program { static void Main(string[] args) { //初始化配置 Mapper.Initialize(cfg => { cfg.AddProfile<UserMappingProfile>(); }); var u1 = Mapper.Map<UserDto>(new User() {Age = 23}); Console.WriteLine(u1.Age); Console.Read(); } }}
AutoMapper可以根据源类型的成员映射到目标类型的构造函数里:
在UserMappingProfile文件中添加配置方法代码:
Mapper.CreateMap<User, UserDto>();
因为AutoMapper会对大小不敏感(case insensitive),所以会将User的Age属性通过UserDto的构造函数进行映射,并对UserDto的私有字段赋值,最后通过公有的Age属性打印出来。
但是,这是在UserDto的构造函数参数名和User的Age属性名相同的情况下,如果不相同呢?比如,将构造函数的参数名改为age1呢?
发现报错了,所以我们要修改配置方法,如下:
Mapper.CreateMap<User, UserDto>().ForCtorParam("age1", opt => opt.MapFrom(src => src.Age));
解释一下ForCtorParam()方法,看名字是针对构造函数参数的,官方解释该方法的作用是对于个别的构造函数参数进行自定义配置。该方法有两个参数,第一个是string类型的构造函数参数名,第二个是一个参数选项Action方法。
我上面这句代码的意思就是说将目标类型的构造函数的参数“age1”从源类型的Age属性进行映射。
AutoMapper支持使用静态服务地址构造自定义值格式化器,自定义值解析器和自定义类型转换器(后面会说):
Mapper.Initialize(cfg => { cfg.ConstructServicesUsing(ObjectFactory.GetInstance); cfg.CreateMap<Source, Destination>(); });
或者在基于实例的容器使用的动态服务地址(包括子容器或嵌套容器):
var dest = Mapper.Map<Source, Destination>(new Source { Value = 15 }, opt => opt.ConstructServicesUsing(childContainer.GetInstance));
条件对象映射器基于源类型和目标类型之间的条件生成新的类型映射。
首先将User和UserDto的构造函数去掉,配置文件中Configure方法中的代码只写入下面这句代码:
AddConditionalObjectMapper().Where((s, d) => d.Name == s.Name + "Dto");
解释:如果目标类型的名称等于源类型的名称加上“Dto”,那么就生成一个源类型和目标类型的对象映射器。添加了这一句,就不需要CreateMap方法了。
在这连个类中加入属性:
public string UserName { get; set; }
可见,即使没有使用CreateMap方法,同样映射成功了。
成员配置就像配置(Configuration)一样,但是你可以完全控制用什么和不用什么。
Mapper.Initialize(cfg => { cfg.AddMemberConfiguration(); });
AddMemberConfiguration()方法以空白状态开启。默认情况下,应用到Configuration中的所有东西都是从这里开始的。
AddMemberConfiguration().AddMember<NameSplitMember>();
AddMemberConfiguration().AddName<ReplaceName>(_ => _.AddReplace("Ä", "A").AddReplace("í", "i"));
AddMemberConfiguration().AddName<PrePostfixName>(_ => _.AddStrings(p => p.Prefixes, "Get", "get").AddStrings(p => p.DestinationPostfixes, "Set"));
AddMemberConfiguration().AddName<SourceToDestinationNameMapperAttributesMember>();
[MapToAttribute("Phone")]public string Tel { get; set; }
public string Phone { get; set; }
var u3 = Mapper.Map<UserDto>(new User() {Tel = "123456"});Console.WriteLine(u3.Phone);//123456
AddMemberConfiguration().AddMember<NameSplitMember>().AddName<PrePostfixName>(_ => _.AddStrings(p => p.Prefixes, "Get"))
AddName和AddMember中的每个类型都是基于ISourceToDestinationNameMapper和IChildMemberConfiguration接口的。也可以创建自己的类通过Lambda语句参数来配置属性,因此你可以微调AutoMapper如何解析属性映射。
配置文件可以加到Profile和ConfigurationStore中。
每一个配置文件都独立于另外一个,且不会共享任何条件。如果一个映射是从一个配置文件(profile)中的AddConditionalObjectMapper生成的,那么可以使用此配置文件的AddMemberConfigurations来解析属性映射。
新闻热点
疑难解答