AutoMapper mapping using an interface against a specific map

I don’t think it’s possible, but I think it’s worth the question.

I have the following types that share the interface (I promise, this is not the question I 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 where does it get interesting / confusing.

It works:

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

This does not work:

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

Now, as a rule, I would not have a problem simply entering the first Map operator with the specified two types of interfaces, but my problem is that the Customer object is buried somewhere.

 public class CustomerOrderDTO { ICustomer customer; } public class CustomerOrderSO { CustomerSO customer; } Mapper.Map<CustomerOrderDTO, CustomerOrderSO>(); 

This does not work because there is no mapping from ICustomer to CustomerSO, so configuration approval is not performed.

I am currently going to solve the problem by following these steps:

 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 object of the DTO type that we have, and then, quite possibly, has a cascading effect.

I understand that technically I could do the following to solve the problem:

 Mapper.Map<CustomerBO, CustomerSO>(); 

However, there are many other properties in CustomerBO that are used in business logic rather than in an interface. Similarly, CustomerSO has many properties in the interface. If I went with the above route, I would have a ton of Ignore () calls, and I would have to map CustomerBO to CustomerSO, and then CustomerSO to CustomerBO, each with its own unique Ignore call list. Using interfaces eliminates the need for Ignore calls because the data that I want to see from one to the other is defined in the interface.

So, in short, my question is: is there a way to tell AutoMapper to use an interface map when it encounters one of the executing classes? If this is not the case, is there any other way (read: better) than calling Map on the MapFrom delegate to ensure that the interface is consistent between the interfaces as needed?

+6
source share
1 answer

In general, you want to configure the mapping on the ICustomer interface and override the destination type using .As<TDestination>() . (Perhaps this is an add-on since you asked the question first.)

This will work for comparisons between two layers, for example, your example:

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

However, extend this to another level, for example, mapping a CustomerModel to a CustomerViewModel and it will fall apart. You can only specify AutoMapper for one type of destination to use.

But, as in the comments above, I would question the reason for the presence of a property introduced as an interface in these other classes. Why does CustomerOrderModel have an ICustomer customer property? Can you replace the client with an instance of CustomerDTO and still have the right program? If you have common behavior for objects containing a client, you can implement these parent interface objects, ICustomerAccessor . Then use an explicit implementation of the interface to add a weaker type property, and it will not have to interfere with this name.

+2
source

Source: https://habr.com/ru/post/924794/


All Articles