[英]AutoMapper mapping using interface vs concrete map
I don't think this is possible, but it's worth the question, I suppose. 我认为这是不可能的,但是我想这是值得提出的问题。
I have the following types that share an interface (I promise, this isn't the same question I've asked before). 我有以下几种共享接口的类型(我保证,这与我之前提出的问题不同)。
public interface ICustomer;
public class CustomerBO : ICustomer
public class CustomerSO : ICustomer // SO is Service Object in this case.
Then, I have the following mapping: 然后,我有以下映射:
Mapper.Map<ICustomer, ICustomer>();
Now, here's where it gets interesting / confusing. 现在,这里变得有趣/令人困惑。
This works: 这有效:
Mapper.Map<ICustomer, ICustomer>(customerSO, new CustomerBO);
This doesn't work: 这不起作用:
Mapper.Map(customerSO, new CustomerBO());
Now, normally I wouldn't have a problem with just typing in the first Map statement with the two interface type defined, but my problem is when the Customer object is buried somewhere. 现在,通常只需输入定义了两个接口类型的第一个Map语句就不会有问题,但是我的问题是,当Customer对象埋在某个地方时。
public class CustomerOrderDTO
{
ICustomer customer;
}
public class CustomerOrderSO
{
CustomerSO customer;
}
Mapper.Map<CustomerOrderDTO, CustomerOrderSO>();
This doesn't work, because there's no mapping from ICustomer to CustomerSO, so config assertion fails. 这是行不通的,因为没有从ICustomer到CustomerSO的映射,因此配置声明失败。
Currently, I'm going around the issue by doing this: 目前,我正在通过以下方法解决此问题:
Mapper.CreateMap<CustomerOrderDTO, CustomerOrderSO>()
.ForMember(desc => dest.customer
, exp => exp.MapFrom(src => Mapper.Map<ICustomer, ICustomer>(src.customer
, new CustomerSO));
However, I would have to do this for every DTO-type object that we have, and then quite possibly have a cascading effect. 但是,我必须对我们拥有的每个DTO类型的对象执行此操作,然后很可能会产生级联效果。
I understand that technically I could do the following to resolve the issue: 我了解从技术上我可以执行以下操作来解决此问题:
Mapper.Map<CustomerBO, CustomerSO>();
However, in CustomerBO there are a lot of other properties used in the business logic not in the interface. 但是,在CustomerBO中,业务逻辑中使用的许多其他属性不在界面中。 Similarly, there are a lot of properties in CustomerSO not in the interface. 同样,CustomerSO中有很多属性不在界面中。 If I were to go with the above route, I would have a ton of Ignore() calls, and I'd have to map CustomerBO to CustomerSO, and then CustomerSO to CustomerBO, each with their own unique list of Ignore calls. 如果要采用上述路线,我将有大量的Ignore()调用,并且必须将CustomerBO映射到CustomerSO,然后将CustomerSO映射到CustomerBO,每个都有自己独特的Ignore调用列表。 Using the interfaces removes the need for the Ignore calls, as the data that I want to be visible from one to the other is defined in the interface. 使用接口消除了对Ignore调用的需求,因为在接口中定义了我希望彼此可见的数据。
So, in short, my question is this: is there some way I can tell AutoMapper to use the interface map when it encounters one of the implementing classes? 简而言之,我的问题是:当遇到一个实现类之一时,有什么方法可以告诉AutoMapper使用接口映射吗? Failing that, is there some other (read: better) way than a Map call in a MapFrom delegate to enforce my interface-to-interface mapping in a as-needed basis? 失败了,是否有其他方法(阅读:更好),而不是MapFrom委托中的Map调用来按需实施我的接口到接口映射?
In general, you'd want to configure a mapping to the ICustomer
interface and override the destination type using .As<TDestination>()
. 通常,您需要配置到ICustomer
接口的映射,并使用.As<TDestination>()
覆盖目标类型。 (Maybe this is an addition since you first asked the question.) (也许这是自您首次提出问题以来的补充内容。)
This would work for mappings between 2 layers, like your example: 这将适用于两层之间的映射,例如您的示例:
Mapper.CreateMap<CustomerDTO, ICustomer>().As<CustomerModel>();
Mapper.CreateMap<CustomerModel, ICustomer>().As<CustomerDTO>();
However, extend this to another layer, such as mapping CustomerModel
to CustomerViewModel
, and this falls apart. 但是,将其扩展到另一层,例如将CustomerModel
映射到CustomerViewModel
,这将分崩离析。 You can only tell AutoMapper one destination type to use for instantiation. 您只能告诉AutoMapper一种用于实例化的目标类型。
But similar to the comments above, I would question the reason for having a property typed as the interface within those other classes. 但是类似于上面的评论,我会质疑在其他类中将属性键入为接口的原因。 Why should a CustomerOrderModel
have a ICustomer customer
property? 为什么CustomerOrderModel
应该具有ICustomer customer
属性? Can you replace customer with an instance of a CustomerDTO
and still have your program be correct? 您可以用CustomerDTO
实例替换客户,但程序仍然正确吗? If you have common behavior for objects that contain a customer, you could have those parent objects implement an interface, ICustomerAccessor
. 如果您对包含客户的对象有共同的行为,则可以让这些父对象实现ICustomerAccessor
接口。 Then, use explicit interface implementation to add the weaker-typed property, and it won't have to interfere with the name. 然后,使用显式接口实现来添加弱类型的属性,而不必干扰名称。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.