6

我认为这是不可能的,但我想这是值得的问题。

我有以下共享接口的类型(我保证,这不是我之前问过的同一个问题)。

public interface ICustomer;

public class CustomerBO : ICustomer

public class CustomerSO : ICustomer // SO is Service Object in this case.

然后,我有以下映射:

Mapper.Map<ICustomer, ICustomer>();

现在,这就是有趣/令人困惑的地方。

这有效:

Mapper.Map<ICustomer, ICustomer>(customerSO, new CustomerBO);

这不起作用:

Mapper.Map(customerSO, new CustomerBO());

现在,通常我只输入定义了两个接口类型的第一个 Map 语句不会有问题,但我的问题是当 Customer 对象被埋在某个地方时。

public class CustomerOrderDTO
{
    ICustomer customer;
}

public class CustomerOrderSO
{
    CustomerSO customer;
}

Mapper.Map<CustomerOrderDTO, CustomerOrderSO>();

这不起作用,因为没有从 ICustomer 到 CustomerSO 的映射,所以配置断言失败。

目前,我正在通过这样做来解决这个问题:

Mapper.CreateMap<CustomerOrderDTO, CustomerOrderSO>()
    .ForMember(desc => dest.customer
        , exp => exp.MapFrom(src => Mapper.Map<ICustomer, ICustomer>(src.customer
            , new CustomerSO));

但是,我必须对我们拥有的每个 DTO 类型对象执行此操作,然后很可能会产生级联效果。

我了解从技术上讲,我可以执行以下操作来解决此问题:

Mapper.Map<CustomerBO, CustomerSO>();

但是,在 CustomerBO 中,还有很多其他属性在业务逻辑中使用,而不是在接口中。同样,CustomerSO中有很多属性不在界面中。如果我采用上述路线,我将有大量的 Ignore() 调用,我必须将 CustomerBO 映射到 CustomerSO,然后将 CustomerSO 映射到 CustomerBO,每个都有自己独特的 Ignore 调用列表。使用接口消除了对忽略调用的需要,因为我希望从一个到另一个可见的数据是在接口中定义的。

所以,简而言之,我的问题是:有什么方法可以告诉 AutoMapper 在遇到其中一个实现类时使用接口映射?如果做不到这一点,是否有其他(阅读:更好的)方法比 MapFrom 委托中的 Map 调用根据需要强制执行我的接口到接口映射?

4

1 回答 1

3

通常,您希望配置到ICustomer接口的映射并使用.As<TDestination>(). (也许这是您第一次提出问题后的补充。)

这适用于 2 层之间的映射,例如您的示例:

Mapper.CreateMap<CustomerDTO, ICustomer>().As<CustomerModel>();
Mapper.CreateMap<CustomerModel, ICustomer>().As<CustomerDTO>();

但是,将其扩展到另一层,例如映射CustomerModelCustomerViewModel,这将分崩离析。您只能告诉 AutoMapper 一种用于实例化的目标类型。

但与上面的评论类似,我会质疑将属性类型化为其他类中的接口的原因。为什么要有CustomerOrderModel财产ICustomer customer?您可以用 a 的实例替换 customerCustomerDTO并且您的程序仍然正确吗?如果您对包含客户的对象有共同的行为,您可以让这些父对象实现一个接口,ICustomerAccessor. 然后,使用显式接口实现添加较弱类型的属性,它不会干扰名称。

于 2015-11-25T21:09:55.913 回答