为什么 AutoMapperExtension 的行为与直接实现不同?

Why would an AutoMapperExtension behave differently from a direct implementation?

我在 AutoMapperConfigRegisterMappings() 中定义了以下映射:

AutoMapper.Mapper.CreateMap<Member, PhotoViewModel>()
            .ForMember(dest => dest.Show, opt => opt.MapFrom(src => src.ShowPhoto))
            .ForMember(dest => dest.Value, opt => opt.MapFrom(src => AutoMapper.Mapper.Map<PhotoValueViewModel>(src));
AutoMapper.Mapper.CreateMap<Member, PhotoValueViewModel>();

此映射映射了 PhotoViewModel 的两个属性。首先它映射 Show 属性 基于 src.ShowPhoto,然后它映射 PhotoValueViewModelValue 属性.

映射有效!不幸的是,我有很多对象需要类似的映射。因此,我尝试将一些实现抽象为 AutoMapperExtension 方法。该方法如下所示:

public static IMappingExpression<TSource, TDestination> ApplyPropertyMapping<TSource, TDestination>
        (this IMappingExpression<TSource, TDestination> iMappingExpression, Expression<Func<TSource, bool?>> show, Expression<Func<TSource, object>> value)
        where TDestination : PropertyViewModel
    {
        iMappingExpression
            .ForMember(dest => dest.Show, opt => opt.MapFrom(show))
            .ForMember(dest => dest.Value, opt => opt.MapFrom(value));
        return iMappingExpression;
    }

我希望此扩展方法允许我将原始映射定义为:

AutoMapper.Mapper.CreateMap<Member, PhotoViewModel>()
    .ApplyPropertyMapping(src => src.ShowPhoto, src => AutoMapper.Mapper.Map<PhotoValueViewModel>(src));

但是没用!现在调用 Mapper.Map<Member, PhotoViewModel>(MemberObject, PhotoViewModelObject)PhotoViewModelObject.Value 属性 设置为空。

造成差异的原因是什么?

其中一些对象的定义是:

public class Member
{
    /**Irrelevant Properties Not Shown**/
    public Guid? PhotoID { get; set; }
    public string PhotoFileName { get; set; }
    public bool? ShowPhoto { get; set; }
}

public class PropertyViewModel
{
    public object Value { get; set; }
    public bool? Show { get; set; }
}

public class PhotoViewModel : PropertyViewModel
{
    public PhotoValueViewModel Value { get; set; }
}

public class PhotoValueViewModel
{
    public Guid? PhotoID { get; set; }
    public string PhotoFileName { get; set; }
    public string PhotoUrl {get {return Utils.GeneratePhotoUrl(PhotoID); } }
}

PhotoViewModel class 包含两个名称为 Value 的属性,其中一个在 PropertyViewModel 中定义,类型为 object。另一个在 PhotoViewModel 中定义并且是 PhotoValueViewModel 类型(这基本上是 hiding 另一个 属性,你应该从 Visual Studio).

在您的扩展方法中,您引用的 PropertyViewModel.Value 类型为 object

这是因为 TDestination 类型在此方法中声明为可从 PropertyViewModel 分配(通过 where TDestination : PropertyViewModel)。

您的扩展方法工作正常,它正在更改 属性 (PropertyViewModel.Value) 的值。

您的原始映射(没有扩展方法)正在将值映射到类型为 PhotoValueViewModel.

PhotoViewModel.Value

您可以使用 Visual Studio 调试器来观察 PropertyViewModel.ValuePhotoViewModel.Value 这两种情况(使用或不使用扩展方法)。