今天我使用AutoMapper v1.1升级了一个功能齐全的应用程序,现在使用AutoMapper v2.1,我遇到了一些我以前从未遇到的问题。
以下是我的代码从 Dto 映射回域对象
的示例public class TypeOne
{
public TypeOne()
{
}
public TypeOne(TypeTwo two)
{
//throw ex if two is null
}
public TypeOne(TypeTwo two, TypeThree three)
{
//throw ex if two or three are null
}
public TypeTwo Two {get; private set;}
public TypeThree Three {get; private set;}
}
public class TypeOneDto
{
public TypeOneDto()
{
}
public TypeTwoDto Two {get; set;}
public TypeThreeDto Three {get; set;}
}
...
Mapper.CreateMap<TypeThreeDto, TypeThree>();
Mapper.CreateMap<TypeTwoDto, TypeTwo>();
Mapper.CreateMap<TypeOneDto, TypeOne>();
var typeOne = Mapper.Map<TypeOne>(typeOneDto);
然而,我遇到的第一个问题是,当其中一个args为null并且应该使用1个arg构造函数时,AutoMapper试图使用带有2个args的构造函数。
然后我尝试使用
Mapper.CreateMap<TypeOneDto, TypeOne>().ConstructUsing(x => new TypeOne());
但是我一直收到“不明确的调用”错误,我无法解决。
然后我尝试了
Mapper.CreateMap<TypeOneDto, TypeOne>().ConvertUsing(x => new TypeOne());
并且使用无参数构造函数成功创建了TypeOne对象,但之后无法设置私有setter属性。
我已经在AutoMapper网站上寻求帮助并下载了源代码以获得良好的外观但是没有得到很少的文档,并且没有很多针对ConstructUsing的单元测试。
有什么明显我错过了我应该用v2.1改变吗?我很惊讶它从v1.1发生了很大的变化。
答案 0 :(得分:49)
您只需将explicit cast添加到
即可Func<ResolutionContext, TypeOne>
以下是代码:
Mapper.CreateMap<TypeOneDto, TypeOne>().ConstructUsing(
(Func<ResolutionContext, TypeOne>) (r => new TypeOne()));
当前版本的AutoMapper的工作原理如下:
按参数计数
对目标类型构造函数进行排序destTypeInfo.GetConstructors().OrderByDescending(ci => ci.GetParameters().Length);
首先使用哪些参数匹配源属性(不检查空值)。在你的情况下,它是带有两个参数的构造函数。
答案 1 :(得分:1)
这是一种扩展方法...
public static void CreateMapWithDefaultConstructor<T, TU>(this Profile profile)
where TU : class, new()
{
profile.CreateMap<T, TU>().ConstructUsing(source => new TU());
}