按照惯例使用自动映射器展开
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),但我怀疑它是否适合基于约定的处理。
您似乎还可以使用 ISourceToDestinationNameMapper
和 AddMemberConfiguration
:
添加自定义名称约定
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。
在我的项目中,我尝试使用 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),但我怀疑它是否适合基于约定的处理。
您似乎还可以使用 ISourceToDestinationNameMapper
和 AddMemberConfiguration
:
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。