使用带默认参数的构造函数自动映射

时间:2014-08-13 14:15:34

标签: c# automapper

想知道解决这个问题的最佳方法:

public class SrcClass{
    public int? Value1 {get;set;}
    public int? Value2 {get;set;}
}

public class DestClass{
    public DestClass(int? value1 = 1){
        Value1 = value1
    }

    public int Value1 {get;set;}
    public int Value2 {get;set;
}

Mapper.createMap<SrcClass,DestClass>()
  .ConstructUsing( src => new DestClass(src.Value1));

var destObject = Mapper.Map<DestClass>(new SrcClass());

现在问题是destObject.Value1null而不是1,因为AutoMapper在运行构造函数后将值设置回src对象的值。我看待它的方式,我有两个不好的选择:

  1. 我可以在createMap方法中重复默认值。但是如果有人在SrcClass的构造函数中添加或更改了默认值并且无法将其添加到映射器配置中,则会在以后引入错误
  2. 我可以在Value1之后添加忽略ConstructUsing,但这会遇到与选项1相同的问题。如果有人进来并使用默认参数添加新值,但是失败要将它添加到映射器,它将成为错误的来源。
  3. 我真正想做的是告诉Automapper只映射构造函数中未传入的属性。不确定框架是否可以处理类似的事情。还有其他想法吗?

1 个答案:

答案 0 :(得分:4)

首先,如果传递 {em>传递 参数,则为省略参数提供默认值与设置默认值之间存在差异。< / p>

换句话说,

null

默认值仅在未指定值时才适用。否则,将使用您的班级用户提供的价值。

我之前只提到这一点,因为如果(new DestClass()).Value1; // Value1 == 1 (new DestClass(null)).Value1; // Value1 == null ConstructUsing,那么您的Value1语句初始化src.Value1为空。换句话说,即使没有AutoMapper在目标对象上进行第二次传递,您也会遇到问题。

现在,即使您通过执行以下操作来解决问题:

null

AutoMapper仍将映射到具有私有设置器的属性,这意味着您仍然无法获得所需的结果。

幸运的是,有一种名为public class DestClass { // Now supplying `null` will result in `Value1` equaling "1" public DestClass(int? value1) { Value1 = value1 ?? 1; } public int? Value1 {get; private set;} public int? Value2 {get; set;} } 的配置方法可用于忽略私有设置器:

IgnoreAllPropertiesWithAnInaccessibleSetter

通过这种方式,您可以获得所需的结果。但是,我已经对你的课程进行了大量修改,这个解决方案可能实际上并不适用于你。

如果对你的应用程序有意义,你也可以公开一个getter并引入一个私有的readonly支持字段以达到类似的效果。

如果这对您不起作用,您最好的选择可能是手动忽略您在构造函数中设置的属性。