如何仅通过接口使用AutoMapper映射两个对象?
问题分析与解决方案
你遇到的问题核心在于:AutoMapper无法自动推断接口对应的具体实现类。当你直接映射接口时,AutoMapper默认会生成一个实现该接口的动态代理对象,但这个对象不会应用你为具体类配置的映射规则,也不会自动填充属性——这就是为什么你得到的是空属性对象。
而当你直接映射具体类时,AutoMapper明确知道要实例化哪个类,并且能正确应用映射规则,所以一切正常。要在不耦合具体类的前提下解决这个问题,你需要在映射配置中明确告诉AutoMapper,当目标是接口时应该实例化哪个具体类,同时确保接口映射能继承具体类的映射规则。
修正后的映射配置
1. 调整Profile配置(适配AutoMapper 6+)
首先,确保你的Profile配置先定义具体类的映射,再定义接口映射,并通过As<>方法指定接口映射对应的具体实例类型:
public class DomainToEntitiesMappingProfile : Profile { public DomainToEntitiesMappingProfile() { // 先配置具体类之间的映射 CreateMap<Customer, CustomerEntity>(); // 配置接口到接口的映射,指定目标实例为CustomerEntity,并继承具体类的映射规则 CreateMap<ICustomer, ICustomerEntity>() .As<CustomerEntity>() .Include<Customer, CustomerEntity>(); } } public class EntitiesToDomainMappingProfile : Profile { public EntitiesToDomainMappingProfile() { CreateMap<CustomerEntity, Customer>(); CreateMap<ICustomerEntity, ICustomer>() .As<Customer>() .Include<CustomerEntity, Customer>(); } }
2. 初始化配置(保持你的现有逻辑即可)
你的MapperConfig不需要改动,确保两个Profile被正确加载:
public class MapperConfig { public static void RegisterMappings() { Mapper.Initialize(c => { c.AddProfile<DomainToEntitiesMappingProfile>(); c.AddProfile<EntitiesToDomainMappingProfile>(); }); } }
3. 验证映射逻辑
现在你的映射代码就能正常工作了:
class Program { static void Main(string[] args) { MapperConfig.RegisterMappings(); ICustomer customer1 = new Customer("John", 30); var customerEntity = Mapper.Map<ICustomer, ICustomerEntity>(customer1); // customerEntity 现在会是 CustomerEntity 实例,且 Age=30,Name="John" var customerReturned = Mapper.Map<ICustomer>(customerEntity); // customerReturned 现在会是 Customer 实例,属性也正确填充 } }
为什么这样能解决问题?
CreateMap<Customer, CustomerEntity>()定义了具体类之间的映射规则,确保属性能正确复制。.As<CustomerEntity>()告诉AutoMapper:当把ICustomer映射到ICustomerEntity时,要实例化CustomerEntity作为目标对象,而不是生成动态代理。.Include<Customer, CustomerEntity>()确保当源是Customer(实现了ICustomer)时,会使用具体类的映射规则,而不是仅用接口的默认规则。
这种方式既保留了接口解耦的优势,又让AutoMapper能正确找到映射规则和实例化目标对象。
内容的提问来源于stack exchange,提问作者user6490459
相关产品推荐
相关产品推荐

