如何在C# AutoMapper Action中实现依赖注入?
解决AutoMapper Mapping Action依赖注入问题
问题背景
在使用AutoMapper的IMappingAction时,由于Action依赖了IACoolService且未提供无参构造函数,运行时和单元测试场景均报错:
Cannot dynamically create an instance of type 'SourceToDestinationAction '. Reason: No parameterless constructor defined.
解决方案
1. Web应用场景
确保以下两点:
- 注册依赖服务:将
IACoolService及其实现类注册到.NET DI容器中:builder.Services.AddScoped<IACoolService, CoolService>(); // 替换为你的实际实现类 - 保持AutoMapper配置不变:原有的
AddAutoMapper配置无需修改,AutoMapper.Extensions.Microsoft.DependencyInjection扩展会自动通过DI容器解析SourceToDestinationAction的依赖:builder.Services .AddAutoMapper((IMapperConfigurationExpression a) => { a.AddProfile<GeneralMappingProfile>(); });
2. 单元测试场景
单元测试中需手动构建服务容器,让AutoMapper能获取到IACoolService的实例:
方法一:使用完整DI容器构建Mapper
// 1. 构建测试服务集合 var services = new ServiceCollection(); // 注册Mock或真实的IACoolService实现 services.AddSingleton<IACoolService>(sp => { var mock = new Mock<IACoolService>(); mock.Setup(s => s.MakeMultiLanguageValue(It.IsAny<string>())) .Returns("Mocked Multi-Language Title"); return mock.Object; }); // 注册AutoMapper并添加Profile services.AddAutoMapper(cfg => cfg.AddProfile<GeneralMappingProfile>()); // 2. 构建服务提供者并获取Mapper var serviceProvider = services.BuildServiceProvider(); var mapper = serviceProvider.GetRequiredService<IMapper>(); // 3. 执行映射测试 var sourceData = new Source { Title = "Test Title" }; var destinationData = mapper.Map<Destination>(sourceData);
方法二:直接给Mapper传入服务提供者
// 1. 创建Mock服务实例 var mockCoolService = new Mock<IACoolService>(); mockCoolService.Setup(s => s.MakeMultiLanguageValue(It.IsAny<string>())) .Returns("Mocked Title"); // 2. 构建服务提供者 var serviceProvider = new ServiceCollection() .AddSingleton(mockCoolService.Object) .BuildServiceProvider(); // 3. 配置AutoMapper并传入服务提供者创建Mapper var config = new MapperConfiguration(cfg => { cfg.AddProfile<GeneralMappingProfile>(); }); var mapper = config.CreateMapper(serviceProvider); // 4. 执行映射 var destination = mapper.Map<Destination>(new Source { Title = "Test" });
核心原因
AutoMapper默认会尝试通过无参构造函数实例化IMappingAction,当Action存在依赖时,必须通过.NET DI容器来解析实例。Web应用中AutoMapper.Extensions.Microsoft.DependencyInjection已集成DI,只需注册好依赖即可;单元测试则需手动构建服务上下文,让AutoMapper能获取到Action所需的依赖。
内容的提问来源于stack exchange,提问作者Jimmyt1988
相关产品推荐
相关产品推荐

