按照惯例使用自动映射器展开

Unflatten by convention with automapper

在我的项目中,我尝试使用 automapper 尽可能按照约定将我的命令对象展开为我的域对象。
当我在映射配置文件中明确映射两个成员时,它会起作用,但 according to the automapper documentation 我认为这也应该按照惯例起作用。 我创建了 a dotnetfiddle 来演示最小情况。

相关问题最终以人们显式添加映射而告终,但这种做法与 Automapper 的构建目的背道而驰,并且与文档相矛盾,不是吗? 它也不适用于展平,所以我认为反向图是一条红鲱鱼。

映射

public class Mapping: Profile
{
    public Mapping()
    {
        this.CreateMap<CreateSelectionCommand, Selection>();
        // .ForMember(selection => selection.Name, opt => opt.MapFrom(x => x.SelectionName))
        .reverseMap()
    }
}

我期望的工作

[Fact]
public void ShouldMapName()
{
    var cmd = new CreateSelectionCommand {SelectionName = "selectionName"};
    var selection = _mapper.Map<Selection>(cmd);

    Assert.Equal(cmd.SelectionName, selection.Name); <== selection.Name == ""
}

类 上下文

public class Selection
{
    public string Name { get; set; }
}

public class CreateSelectionCommand
{
    public string SelectionName { get; set; }
}

我是误读了文档还是遗漏了什么?

扁平化是关于将嵌套的“复杂”对象映射到“更高”级别的属性,即在您的情况下,如果 CreateSelectionCommand 具有 属性 Selection 类型 Name 属性 它将映射到目标类型中的 SelectionName(参见 this fiddle)。

您可以通过添加以下内容来尝试使用 prefixes

cfg.RecognizePrefixes("Selection");

您的配置(参见 this fiddle),但我怀疑它是否适合基于约定的处理。

您似乎还可以使用 ISourceToDestinationNameMapperAddMemberConfiguration:

添加自定义名称约定
class TypeNamePrefixedSourceToDestinationNameMapper : ISourceToDestinationNameMapper
{
    public MemberInfo GetMatchingMemberInfo(IGetTypeInfoMembers getTypeInfoMembers, TypeDetails typeInfo,
        Type destType,
        Type destMemberType, string nameToSearch)
    {
        return getTypeInfoMembers.GetMemberInfos(typeInfo)
            .FirstOrDefault(mi => mi.Name == destType.Name + nameToSearch);
    }
}

var config = new MapperConfiguration(cfg =>
{
    cfg.AddMemberConfiguration().AddName<TypeNamePrefixedSourceToDestinationNameMapper>();

    // ...
}

至少它在这个简单的例子中有效,见 this fiddle