什么是AutoMapper ?!
Automapper是一个object-object mapping(对象映射)的DTO(数据传输)工具,一般主要用于两个对象之间数据映射和交换。当然你也可以定义映射规则写对象的映射。
默认的映射规则是遵循的扁平化映射原则:只要Destination类型的成员名字与Source类型的成员名字匹配(成员名称不区分大小写),并且成员类型相同就直接会将值传递给Destination类型。
以往我们进行数据实体的传输时的步骤应该是
Customer customer = new Customer()
{
name = "叶大白",
age = "24",
adress = "合肥"
};
Customer2 customer2 = new Customer2()
{
name = customer.name,
age = customer.age,
adress = customer.adress
};
而现在仅仅只需要简单一句话就可以全局配置这种类型的转换了
var info2 = _mapper.Map<Customer2>(customer);
AutoMapper的部署
1.引用Nuget包 =>
AutoMapper
AutoMapper.Extensions.Microsoft.DependencyInjection (辅助映射的扩展包)
2.注入服务 (在startup 的ConfigureServices中注入服务)
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
services.AddAutoMapper(); //引用autoMapper的服务
}
3.定义全局映射规则 类继承Profile
//automapper的 映射规则。全局通用。
public class AutoMapperProfileConfiguration : Profile
{
//匹配规则 和路由匹配一致。从上到下扫描。取最下面的那个
public AutoMapperProfileConfiguration()
{
CreateMap<Customer, Customer2>(); //创建的映射规则
}
}
4.项目中的使用
[Route("api/test")]
[ApiController]
public class ValuesController : ControllerBase
{
private readonly IMapper _mapper;
public ValuesController([FromServices] IMapper mapper) => _mapper = mapper;
[HttpGet("Demo")]
//automapperDemo
public void AutoDemo()
{
var info = _mapper.Map<customer, customer2>(customer);
}
}
automapper的匹配规则是从上至下的。 如果匹配多个符合条件默认取最后一个匹配到的规则形式。进行DTO转换
AutoMapper的应用场景 :
public class Customer //客户
{
public string name { get; set; }
public string age { get; set; }
public string profession { get; set; } //专业
}
public class Customer2 //客户2
{
public string name { get; set; }
public string age { get; set; }
public string profession { get; set; } //专业
}
场景1. 直接的转换。
添加的规则: CreateMap<Customer, Customer2>();
场景2. customer2的字段名字不对称。
public class Customer2 //客户2
{
public string customername { get; set; }
public string age { get; set; }
public string profession { get; set; } //专业
}
CreateMap<Customer, Customer2>()
.ForMember(s => s.customername, sp => sp.MapFrom(src => src.name));
//s指代的是映射后的字段。 sp 指代的是映射源数据的来源字段
场景3. 希望将映射后的数据进行部分数据的隐藏/更改
CreateMap<Customer, Customer2>() //(source是源数据, dto是转换后的映射的内容)
//映射发生之前对数据的修改
.BeforeMap((source, dto) =>
{
//可以较为精确的控制输出数据格式
//dto.CreateTime = Convert.ToDateTime(source.CreateTime).ToString("yyyy-MM-dd");
//dto.customername
})
//映射发生之后
.AfterMap((source, dto) =>
{
dto.customername = source.name.Substring(0, 1) + "**";
//if (dto.Count >0)
//{
// dto = dto;
//}
//else
//{
// dto = new List<customer4>();
//}
});
.beforeMapper是在映射发生之前。.aftermap是在映射发生之后 。除了可以写业务也可以进行逻辑判断等等同于个匿名方法。
场景4 List的转换
CreateMap<List<a>, List<a>>();
var lista = new List<a>()
{
new a() { name = "a",age="18",adress="合肥" },
new a() { name = "a",age="18",adress="合肥" },
new a() { name = "a",age="18",adress="合肥" },
new a() { name = "a",age="18",adress="合肥" }
};
var resultlist = _mapper.Map<List<b>>(lista);
场景5 自动分割映射(Flattening)
public class Order
{
public Customer Customer { get; set; }
public decimal GetTotal()
{
return 1;
}
}
public class Customer
{
public string Name { get; set; }
}
public class OrderDto
{
public string CustomerName { get; set; }
public decimal Total { get; set; }
}
CreateMap<Order, OrderDto>();
这种嵌套形式的实体映射,规则上和普通的实体映射一样。因为遵循了自动分割映射原则。
- 名称相同的属性进行映射,不区分大小写。
- 带Get前缀的方法进行映射,如例子中:
映射器会把Order中的GetTotal分割成Get、Total 2个词, 把分割出来的Total与OrderDto中的Order进行匹配映射。 - 目标类型属性分割,如例子中: 映射器会把OrderDto中的CustomerName分割成Customer、Name。然后在Order中去Customer类属性中查找Name的属性。
场景-测试 如果想检测我们的所有映射是否有效。添加一下代码。在匹配的地方。如果无效会抛出异常。
Mapper.AssertConfigurationIsValid();
AssertConfigurationIsValid执行验证期间,AutoMapper会检查每个目标类型的属性,逐一去匹配源中是否存在合适相等的类型,如果有字段没有映射成功就会抛出异常。
本文参考文章: https://www.cnblogs.com/mushroom/p/4291975.html