使用IMapper依赖注入时如何配置AutoMapper多语言条件映射
基于AutoMapper动态多语言映射实现方案
原写法无法生效的核心原因:MappingProfile是AutoMapper在应用启动阶段一次性初始化的单例配置,构造函数传入的lang只会在首次初始化时读取一次,无法获取每次接口请求动态变化的语言参数,需要改用运行时上下文传参的方式实现动态映射,最终效果和手动遍历赋值完全一致。
步骤1:修正MappingProfile配置
移除构造函数的lang参数,映射规则中通过AutoMapper的解析上下文读取每次请求传入的语言值,同名字段无需额外配置,AutoMapper会自动完成映射:
public class MappingProfile : Profile { public MappingProfile() { CreateMap<Product, ProductDTO>() // 多语言商品名称映射 .ForMember(dest => dest.Name, opt => opt.MapFrom((src, _, _, context) => context.Items["lang"]?.ToString() == "ar" ? src.NameAr : src.NameEn )) // 多语言国家名称映射 .ForMember(dest => dest.CountryName, opt => opt.MapFrom((src, _, _, context) => context.Items["lang"]?.ToString() == "ar" ? src.Country.NameAr : src.Country.NameEn )) // 固定业务规则映射 .ForMember(dest => dest.HaveSection, opt => opt.MapFrom(src => src.Id != 0)) .ForMember(dest => dest.ByPiece, opt => opt.MapFrom(src => src.ProductUnit == Units.number)) .ReverseMap(); } }
注:
Id、Price、HasOffer、OfferPrice这些名称和类型完全一致的字段,AutoMapper会自动匹配映射,不需要手动编写配置,和手动逐字段赋值的逻辑完全对齐。
步骤2:接口调用映射时传入语言参数
在接口中拿到请求头的lang值后,调用IMapper.Map方法时将lang传入映射上下文字典,无需手动循环遍历赋值:
[HttpGet("Products")] public async Task<IActionResult> Get(int SectionId ,bool IsSection, [FromHeader] string lang) { // 原有业务逻辑:查询商品数据 var products = await _productRepository.GetListAsync(SectionId, IsSection); // 执行映射,传入当前请求的语言参数 var productDTOs = _mapper.Map<List<ProductDTO>>( products, options => options.Items["lang"] = lang ); return Ok(productDTOs); }
可选优化:复用多语言映射逻辑
如果项目中存在大量多语言字段映射,可以抽离通用解析器减少重复代码:
// 通用多语言值解析器 public class MultiLanguageResolver : IMemberValueResolver<object, object, string, string> { public string Resolve(object source, object destination, string arValue, string enValue, ResolutionContext context) { return context.Items["lang"]?.ToString() == "ar" ? arValue : enValue; } } // Profile中使用方式 CreateMap<Product, ProductDTO>() .ForMember(dest => dest.Name, opt => opt.MapFrom<MultiLanguageResolver, string>(src => src.NameAr, src => src.NameEn)) .ForMember(dest => dest.CountryName, opt => opt.MapFrom<MultiLanguageResolver, string>(src => src.Country.NameAr, src => src.Country.NameEn)) // 其余固定映射规则保持不变
该实现是线程安全的,每个请求独立传入自己的语言参数,不会出现不同请求语言值串扰的问题。
内容的提问来源于stack exchange,提问作者mahmoud sabry
相关产品推荐
相关产品推荐

