使用界面与具体地图的AutoMapper映射

时间:2012-09-06 20:20:59

标签: c# interface automapper automapper-2

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

我有以下类型共享界面(我保证,这不是我之前提出的问题)。

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调用列表。使用接口消除了对Ignore调用的需要,因为我希望从一个到另一个可见的数据在接口中定义。

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

1 个答案:

答案 0 :(得分:2)

通常,您需要配置到ICustomer接口的映射,并使用.As<TDestination>()覆盖目标类型。 (自从你第一次提出问题以来,这可能是一个补充。)

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

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

但是,将此扩展到另一个图层,例如将CustomerModel映射到CustomerViewModel,这就会崩溃。您只能告诉AutoMapper一个目标类型用于实例化。

但是与上面的评论类似,我会质疑在其他类中输入属性作为接口的原因。为什么CustomerOrderModelICustomer customer属性?您是否可以使用CustomerDTO的实例替换客户,并且仍然可以使您的程序正确无误?如果对包含客户的对象有共同行为,则可以让这些父对象实现接口ICustomerAccessor。然后,使用explicit interface implementation添加较弱类型的属性,并且不必干扰名称。