你可以看看这个自定义扩展方法 http://matthewmanela.com/blog/update-on-inheriting-base-type-mappings-with-automapper/。源代码也可以在Github上找到here https://github.com/mmanela/InheritedAutoMapper/tree/master/MappingExtensions.
扩展方法有我现在能想到的树缺点。首先是Mapper.AssertConfigurationIsValid()
将失败,因为它找不到基本映射中定义的属性映射。解决方案是忽略底映射中定义的任何提供的成员映射。
第二是扩展方法依赖于静态Mapper
班级。如果这就是您使用 AutoMapper 的方式,那么就没有问题。如果您有多个映射引擎和/或针对 AutoMapper 接口编写代码,则无法使用此扩展方法。为了支持这两种情况,我们需要添加两个可选参数:IConfigurationProvider
and IMappingEngine
.
我尽量避免使用静态Mapper
类并通过一个方法在我需要的地方注入接口IoC https://stackoverflow.com/questions/3058/what-is-inversion-of-control容器。
第三个是扩展方法不返回IMappingExpression<TSource, TDestination>
并禁止覆盖基本成员映射。为了解决这个问题,我们返回IMappingExpression<TSource, TDestination>
并取消所有成员的条件。
这会产生以下代码:
public enum WithBaseFor
{
Source,
Destination,
Both
}
public static class AutoMapperExtensions
{
public static IMappingExpression<TSource, TDestination> InheritMappingFromBaseType<TSource, TDestination>(
this IMappingExpression<TSource, TDestination> mappingExpression,
WithBaseFor baseFor = WithBaseFor.Both,
IMappingEngine mappingEngine = null,
IConfigurationProvider configurationProvider = null)
{
Type sourceType = typeof (TSource);
Type destinationType = typeof (TDestination);
Type sourceParentType = baseFor == WithBaseFor.Both || baseFor == WithBaseFor.Source
? sourceType.BaseType
: sourceType;
Type destinationParentType = baseFor == WithBaseFor.Both || baseFor == WithBaseFor.Destination
? destinationType.BaseType
: destinationType;
mappingExpression
.BeforeMap((sourceObject, destObject) =>
{
if (mappingEngine != null)
mappingEngine.Map(sourceObject, destObject, sourceParentType, destinationParentType);
else
Mapper.Map(sourceObject, destObject, sourceParentType, destinationParentType);
});
TypeMap baseTypeMap = configurationProvider != null
? configurationProvider.FindTypeMapFor(sourceParentType, destinationParentType)
: Mapper.FindTypeMapFor(sourceParentType, destinationParentType);
if (baseTypeMap == null)
{
throw new InvalidOperationException(
string.Format("Missing map from {0} to {1}.", new object[]
{
sourceParentType.Name,
destinationParentType.Name
}));
}
foreach (PropertyMap propertyMap in baseTypeMap.GetPropertyMaps())
mappingExpression.ForMember(propertyMap.DestinationProperty.Name, opt => opt.Ignore());
return mappingExpression;
}
}
Usage
CreateMap<SourceClass, TargetBaseClass>()
.ForMember(dst => dst.TargetProperty1, opt => opt.MapFrom(src => src.SourceProperty1))
.ForMember(dst => dst.TargetProperty2, opt => opt.MapFrom(src => src.SourceProperty2));
CreateMap<SourceClass, TargetClass1>()
.ForMember(dst => dst.TargetProperty3, opt => opt.MapFrom(src => src.SourceProperty3))
.InheritMappingFromBaseType(WithBaseFor.Destination)
;
CreateMap<SourceClass, TargetClass2>()
.ForMember(dst => dst.TargetProperty4, opt => opt.MapFrom(src => src.SourceProperty4))
.InheritMappingFromBaseType(WithBaseFor.Destination)
;
也许仍然有一些场景没有涵盖,但它肯定可以解决您的问题,这样您就不需要编写特定的扩展方法。