在C# AutoMapper中如何避免重复忽略基类ActionedBy、ActionedAt字段
AutoMapper批量忽略通用字段优化方案
你当前的实现存在明显的代码重复问题,不属于最优方案。AutoMapper内置了多种批量配置能力,可以统一处理这类通用字段忽略需求,无需为每个映射单独配置,以下是三种常用的优化方案:
方案1:全局映射过滤(适用所有映射都需要忽略这两个字段的场景)
直接在Profile构造函数中配置全局属性映射规则,符合条件的字段自动跳过映射,无需在每个CreateMap中单独加忽略配置:
public class MappingProfile : Profile { public MappingProfile() { // 全局配置:所有映射都自动忽略ActionedAt、ActionedBy字段 ShouldMapProperty = prop => prop.Name is not (nameof(ActionedAt) or nameof(ActionedBy)); // 后续所有CreateMap无需再加Ignore配置,直接简写即可 CreateMap<OnboardingRules.Definition.AnnualCardTurnoverCustomRuleDefinition, AnnualCardTurnoverCustomRuleDefinitionUpdatedMessage>(); CreateMap<OnboardingRules.Definition.ArrayComparisonRuleDefinition, ArrayComparisonRuleDefinitionUpdatedMessage>(); // 剩余其他映射规则同理省略忽略配置 } }
如果只需要对特定类型的目标类忽略这两个字段,可以加类型判断进一步缩小规则生效范围:
ShouldMapProperty = (propInfo, destinationType) => { // 仅对实现了IUpdateMessage接口的目标类忽略两个审计字段 if (typeof(IUpdateMessage).IsAssignableFrom(destinationType) && propInfo.Name is nameof(IUpdateMessage.ActionedAt) or nameof(IUpdateMessage.ActionedBy)) { return false; } return true; };
方案2:扩展方法封装(适用仅部分映射需要忽略这两个字段的场景)
把重复的忽略逻辑封装为通用扩展方法,仅需要忽略字段的映射调用该方法即可,灵活性最高:
// 定义AutoMapper扩展方法 public static class AutoMapperAuditIgnoreExtensions { public static IMappingExpression<TSource, TDest> IgnoreAuditFields<TSource, TDest>(this IMappingExpression<TSource, TDest> mappingExp) { return mappingExp .ForMember(nameof(ActionedAt), opt => opt.Ignore()) .ForMember(nameof(ActionedBy), opt => opt.Ignore()); } } // 配置映射时调用 public class MappingProfile : Profile { public MappingProfile() { CreateMap<OnboardingRules.Definition.AnnualCardTurnoverCustomRuleDefinition, AnnualCardTurnoverCustomRuleDefinitionUpdatedMessage>() .IgnoreAuditFields(); CreateMap<OnboardingRules.Definition.ArrayComparisonRuleDefinition, ArrayComparisonRuleDefinitionUpdatedMessage>() .IgnoreAuditFields(); // 剩余其他映射同理调用扩展方法即可 } }
方案3:基类映射继承(适用源/目标类都有统一公共基类的场景)
如果你的所有RuleDefinition都继承自同一个基类,所有UpdatedMessage也继承自同一个包含ActionedAt、ActionedBy的基类,可以配置基类映射规则,子类映射直接继承配置即可:
public class MappingProfile : Profile { public MappingProfile() { // 先配置基类映射,添加忽略规则 CreateMap<BaseRuleDefinition, BaseUpdatedMessage>() .ForMember(x => x.ActionedAt, opt => opt.Ignore()) .ForMember(x => x.ActionedBy, opt => opt.Ignore()); // 子类映射通过IncludeBase继承基类的忽略配置 CreateMap<OnboardingRules.Definition.AnnualCardTurnoverCustomRuleDefinition, AnnualCardTurnoverCustomRuleDefinitionUpdatedMessage>() .IncludeBase<BaseRuleDefinition, BaseUpdatedMessage>(); CreateMap<OnboardingRules.Definition.ArrayComparisonRuleDefinition, ArrayComparisonRuleDefinitionUpdatedMessage>() .IncludeBase<BaseRuleDefinition, BaseUpdatedMessage>(); // 剩余其他子类映射同理继承即可 } }
方案选型建议
- 全局配置方案代码量最小,适合全项目统一不需要映射这两个审计字段的场景
- 扩展方法方案灵活性最高,适合只有部分映射需要忽略字段的场景
- 基类继承方案类型安全性最高,适合源和目标都有统一基类约定的场景
内容的提问来源于stack exchange,提问作者Tom
相关产品推荐
相关产品推荐

