AutoMapper是基于约定的,面向对象的映射器。 面向对象的映射器是将输入对象转换为不同类型的输出对象的映射器。 AutoMapper也可以用于映射相似或不相似的对象(即,具有相同或不同的属性的对象)。
在上一篇文章中,我们检查了AutoMapper的基本功能。 在本文中,我们将探讨AutoMapper的一些高级功能。
在Visual Studio中创建一个ASP.Net Core项目
首先,让我们在Visual Studio中创建一个新的ASP.Net Core项目。 请注意,您可以创建任何项目(例如,MVC或什至是控制台应用程序)来使用AutoMapper。 如果您的系统中安装了Visual Studio 2019,请按照下面概述的步骤创建一个新的ASP.Net Core项目。
- 启动Visual Studio IDE。
- 点击“创建新项目”。
- 在“创建新项目”窗口中,从显示的模板列表中选择“ ASP.Net Core Web应用程序”。
- 点击下一步。
- 在接下来显示的“配置新项目”窗口中,指定新项目的名称和位置。
- 单击创建。
- 在接下来显示的“创建新的ASP.Net Core Web应用程序”窗口中,从顶部的下拉菜单中选择.Net Core作为运行时,并选择ASP.Net Core 2.2(或更高版本)。
- 选择“ Web应用程序”作为项目模板,以创建一个新的ASP.Net Core Web应用程序。
- 确保未选中“启用Docker支持”和“配置HTTPS”复选框,因为我们此处将不再使用这些功能。
- 确保将身份验证设置为“无身份验证”,因为我们也不会使用身份验证。
- 单击创建。
现在,您应该已经准备好在Visual Studio中运行一个新的ASP.Net Core项目。 我们将在本文的后续部分中使用该项目,以说明一些使用AutoMapper的高级操作。
安装AutoMapper
要开始使用AutoMapper,应在项目中安装必要的软件包。 为此,您可以在NuGet软件包管理器控制台窗口中使用以下命令:
Install-Package AutoMapper
Install-Package AutoMapper.Extensions.Microsoft.DependencyInjection
假设安装成功,您都可以在项目中使用AutoMapper。
配置自动映射器
成功安装AutoMapper之后,可以通过在IServiceCollection实例上调用AddAutoMapper方法来对其进行配置。
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion
(CompatibilityVersion.Version_2_2);
services.AddAutoMapper();
}
使用配置文件在AutoMapper中指定映射信息
您可以使用配置文件来组织映射集合。 若要创建配置文件,您需要创建一个扩展AutoMapper库的Profile类的类。 然后,您可以将必要的映射配置信息添加到刚创建的类的构造函数中。 CreateMap方法用于创建两种类型之间的映射。
下列类显示如何通过扩展Profile类并指定映射信息来创建名为AuthorProfile的类。
public class AuthorProfile : Profile
{
public AuthorProfile()
{
CreateMap<AuthorModel, AuthorDTO>();
}
}
在AutoMapper中使用ReverseMap()方法
请注意,上面的示例是单向映射。 同样,假设您已使用CreateMap方法定义了单向映射,如下面的代码片段所示。
AutoMapper.Mapper.CreateMap<Author, AuthorModel>();
现在,您可以将Author类的实例映射到AuthorModel,如下所示。
var authorModel = AutoMapper.Mapper.Map<AuthorModel>(author);
现在,假设您想将AuthorModel实例映射回Author实例。 您可以尝试使用以下代码。
var author = AutoMapper.Mapper.Map<Author>(authorModel);
但是,请注意,这将引发运行时异常。 发生异常是因为AutoMapper运行时缺少执行此映射所需的知识。 实现此反向映射的一种方法是从头开始重新创建映射。 一种更简单更好的方法是通过使用CreateMap方法之外的ReverseMap方法,如下面的代码片段所示。
AutoMapper.Mapper.CreateMap<Author, AuthorModel>().ReverseMap();
在AutoMapper中使用ForMember()和MapFrom()方法
下一个示例将使用上一篇有关AutoMapper的文章中的AuthorModel和AuthorDTO类。 您可以在此处参考该文章 。
以下代码段说明了如何映射AuthorModel和AuthorDTO类的对象。
var author = new AuthorModel();
author.Id = 1;
author.FirstName = "Joydip";
author.LastName = "Kanjilal";
author.Address = "Hyderabad";
var authorDTO = _mapper.Map<AuthorDTO>(author);
现在,假设在AuthorModel类中名为Address的属性已更改为Address1。
public class AuthorModel
{
public int Id
{
get; set;
}
public string FirstName
{
get; set;
}
public string LastName
{
get; set;
}
public string Address1
{
get; set;
}
}
然后,您可以在AuthorProfile类中更新映射信息,如下所示。
public class AuthorProfile : Profile
{
public AuthorProfile()
{
CreateMap<AuthorModel, AuthorDTO>().ForMember
(destination => destination.Address,
map => map.MapFrom(source => source.Address1));
}
}
在AutoMapper中使用NullSubstitute
假设AuthorModel中的Address字段为null,并且您希望使用“ No data”之类的东西来代替null值。 这是NullSubstitution起作用的地方。 以下代码段说明了如何使用“无数据”替换空值。
AutoMapper.Mapper.CreateMap<AuthorModel, AuthorDTO>()
.ForMember(destination => destination.Address, opt => opt.NullSubstitute("No data"));
在AutoMapper中映射之前和之后使用
考虑以下两个类。
public class OrderModel
{
public int Id { get; set; }
public string ItemCode { get; set; }
public int NumberOfItems { get; set; }
}
public class OrderDTO
{
public int Id { get; set; }
public string ItemCode { get; set; }
public int NumberOfItems { get; set; }
}
您可以利用BeforeMap()方法执行一些计算或初始化源或目标实例中的数据成员。 以下代码段说明了如何实现此目的。
Mapper.Initialize(cfg => {
cfg.CreateMap()
.BeforeMap((src, dest) => src.NumberOfItems = 0)
});
完成映射后,可以使用AfterMap()方法对目标对象执行操作。 这是在目标实例上使用AfterMap()方法的方法。
public OrderDTO MapAuthor(IMapper mapper, OrderDTO orderDTO)
{
return mapper.Map<OrderModel, OrderDTO>(orderDTO, opt =>
{
opt.AfterMap((src, dest) =>
{
dest.NumberOfItems =
_orderService.GetTotalItems(src);
});
});
}
在AutoMapper中使用嵌套映射
AutoMapper也可以用于映射嵌套对象。 请考虑以下域类。
public class Order
{
public string OrderNumber { get; set; }
public IEnumerable<OrderItem> OrderItems { get; set; }
}
public class OrderItem
{
public string ItemName { get; set; }
public decimal ItemPrice { get; set; }
public int ItemQuantity { get; set; }
}
考虑以下代表数据传输对象的类。
public class OrderDto
{
public string OrderNumber { get; set; }
public IEnumerable<OrderItemDto> OrderItems { get; set; }
}
public class OrderItemDto
{
public string ItemName { get; set; }
public decimal ItemPrice { get; set; }
public int ItemQuantity { get; set; }
}
您可以使用以下代码建立映射。
var orders = _repository.GetOrders();
Mapper.CreateMap<Order, OrderDto>();
Mapper.CreateMap<OrderItem, OrderItemDto>();
var model = Mapper.Map<IEnumerable<Order>, IEnumerable<OrderDto>>(orders);
AutoMapper使您能够以最少的配置映射对象。 您甚至可以使用自定义解析器来映射具有不同数据结构的对象。 自定义解析器可以生成与目标对象具有相同结构的交换对象,以便AutoMapper运行时可以在运行时映射类型。
From: https://www.infoworld.com/article/3406800/more-advanced-automapper-examples-in-net-core.html