c# - 如何在AutoMapper的MapperConfiguration中使用mapper.Map?

标签 c# .net mapping automapper

我需要使用 AutoMapper 将一个对象映射到另一个对象。棘手的问题是如何访问映射配置内部或自定义类型转换器内部的映射器实例(IMapper 实例)?

下面的代码不起作用,但它是我想要实现的示例 - 请注意 mapper.Map 调用并假设映射 Customer => CustomerDtoCustomer => DetailedCustomerDto 已定义。

var config = new MapperConfiguration(
    cfg => cfg.CreateMap<Order, OrderDto>()
        .ForMember(dst => dst.Customer, src => src.ResolveUsing(o => {
            return o.Type == 1
                ? mapper.Map<Customer, CustomerDto>(o.Customer)
                : mapper.Map<Customer, DetailedCustomerDto>(o.Customer)
            })
    );

客户端部分是:

var mapper = config.CreateMapper();
var orderDto = mapper.Map<Order, OrderDto>(order);

我要映射的对象的简化版本是:

public class Order
{
    public int Type { get; set; }
    public Customer Customer { get; set; }
}

public class Customer
{
    public long Id { get; set; }
    public string Name { get; set; }
}

public class OrderDto
{
    public CustomerDto Customer { get; set; }
}

public class CustomerDto
{
    public long Id { get; set; }
}

public class DetailedCustomerDto : CustomerDto
{
    public string Name { get; set; }
}

正如您从上面的代码中看到的,根据 Order.Type 的值,映射器应该将属性 Order.Customer 映射到不同的目标。由于一个目标 (DetailedCustomerDto) 从另一个目标 (CustomerDto) 继承,它变得有点棘手。

请注意,过时且已弃用的静态方法 Mapper.Map 不是一个选项

最佳答案

自 AutoMapper 8.0 起 以下 5.1.1 的答案仍然适用,但请注意 ResolveUsing 的使用已被重载替换为 MapFrom , 但签名在其他方面保持一致。

自 AutoMapper 5.1.1 起

您可以使用 ResolveUsing 的另一个重载来访问映射器有四个参数,第四个是ResolutionContext ( context.Mapper ):

var config = new MapperConfiguration(
    cfg => {
        cfg.CreateMap<Customer, CustomerDto>();
        cfg.CreateMap<Customer, DetailedCustomerDto>();
        cfg.CreateMap<Order, OrderDto>()
             .ForMember(dst => dst.Customer, src => src.ResolveUsing((order, orderDto, i, context) => {
                return order.Type == 1
                ? context.Mapper.Map<Customer, CustomerDto>(order.Customer)
                : context.Mapper.Map<Customer, DetailedCustomerDto>(order.Customer);
        }));
 });

 var orderTypeOne = new Order();
 orderTypeOne.Type = 1;
 orderTypeOne.Customer = new Customer() {
    Id = 1
 };

 var dto = config.CreateMapper().Map<Order, OrderDto>(orderTypeOne);
 Debug.Assert(dto.Customer.GetType() == typeof (CustomerDto));

 var orderTypeTwo = new Order();
 orderTypeTwo.Type = 2;
 orderTypeTwo.Customer = new Customer() {
     Id = 1
 };
 dto = config.CreateMapper().Map<Order, OrderDto>(orderTypeTwo);
 Debug.Assert(dto.Customer.GetType() == typeof (DetailedCustomerDto));

AutoMapper 5.1.1 之前

您可以使用 ResolveUsing 的另一个重载来访问映射器有两个参数,第一个是ResolutionResult ( result.Context.Engine.Mapper ):

var config = new MapperConfiguration(
    cfg => {
        cfg.CreateMap<Customer, CustomerDto>();
        cfg.CreateMap<Customer, DetailedCustomerDto>();
        cfg.CreateMap<Order, OrderDto>()
             .ForMember(dst => dst.Customer, src => src.ResolveUsing((result, order) => {
                return order.Type == 1
                ? result.Context.Engine.Mapper.Map<Customer, CustomerDto>(order.Customer)
                : result.Context.Engine.Mapper.Map<Customer, DetailedCustomerDto>(order.Customer);
        }));
 });

 var orderTypeOne = new Order();
 orderTypeOne.Type = 1;
 orderTypeOne.Customer = new Customer() {
    Id = 1
 };

 var dto = config.CreateMapper().Map<Order, OrderDto>(orderTypeOne);
 Debug.Assert(dto.Customer.GetType() == typeof (CustomerDto));

 var orderTypeTwo = new Order();
 orderTypeTwo.Type = 2;
 orderTypeTwo.Customer = new Customer() {
     Id = 1
 };
 dto = config.CreateMapper().Map<Order, OrderDto>(orderTypeTwo);
 Debug.Assert(dto.Customer.GetType() == typeof (DetailedCustomerDto));

关于c# - 如何在AutoMapper的MapperConfiguration中使用mapper.Map?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37072286/

相关文章:

nhibernate - 流利的NHibernate HasManyToMany()映射

java - 使用 Castor,如何将 Java 类 "java.util.ArrayList"映射到元素 "ArrayList",同时为其包含的对象生成元素?

java - 层之间枚举的映射

c# - 代码隐藏中的 Datagrid 绑定(bind)与 XAML 中的 DataGrid 绑定(bind)

c# - 为什么我的 CreateRibbonExtensibilityObject 方法没有被调用?

c# - 如果所有 id 都相同,Selenium C# 有没有办法在表上找到特定的更新按钮?

c# - 无法在 TabControl 内的 TextBox 上设置 WordWrap 选项

c# - 如何使用 .NET ApplicationPool 类更改应用程序池的用户名和密码?

c# - 如何为 API 配置注入(inject)第二个 databaseContext

.net - NGEN 和平台目标是同一个东西吗?