在某些但不是所有AutoMapper映射中对浮动属性的特殊处理

时间:2014-03-18 15:18:38

标签: c# automapper

我刚开始使用C#中的AutoMapper。我已成功创建了这样的映射:

Mapper.CreateMap<InputTypeA, OutputTypeA>()

我还找到了一种向特定属性添加逻辑的方法,比如将日期(在InputTypeA中)格式化为特定格式的字符串(在OutputTypeA中)。

.ForMember(
    dest => dest.MyDateProperty,
    opt => opt.ResolveUsing(
        src => String.Format("{0:yyyy-MM-dd}", src.MyDateProperty)));

现在我需要为许多浮动属性做同样的事情,但我想知道是否有一个简短/简单的方法来执行此操作,除了复制一段代码,如上面的代码,用于每个需要的属性遵循这条规则。

我发现我可以创建一个这样的新地图,用于将浮点数映射到字符串:

Mapper.CreateMap<float,string>()
    .ConvertUsing(src =>
        String.Format(CultureInfo.InvariantCulture.NumberFormat, "{0:0.00}", src));

这是有效的,但是太通用了,因为我还有另一种类型的映射(让我们称之为InputTypeB),它也包含浮动属性,需要区别对待。

Mapper.CreateMap<InputTypeB, OutputTypeB>()

如何只将float-to-string映射成为第一个映射的一部分?

2 个答案:

答案 0 :(得分:1)

您可以为需要处理的每个案例创建自定义值解析器。然后将这些应用于映射中的相应成员。

举个例子,我需要从TypeA映射到TypeB,我只希望DateB使用自定义转换:

 public class TypeA {
    public DateTime DateA { get; set; } 
    public DateTime DateB { get; set; }
}

public class TypeB {
    public string DateA { get; set; }
    public string DateB { get; set; }
}

我创建了一个自定义解析器:

 class DateStringResolver : ValueResolver<DateTime, string> {
     protected override string ResolveCore(DateTime source) {
         return String.Format("{0:yyyy-MM-dd}", source);
     }
 }

然后在我的mapper配置中:

                 Mapper.CreateMap<TypeA, TypeB>()
                 //Only Date B will use our custom resolver
                 .ForMember(d => d.DateB, opt => opt.ResolveUsing<DateStringResolver>().FromMember(src => src.DateA));

现在可以在任何需要的地方应用解析器。

文档:https://github.com/AutoMapper/AutoMapper/wiki/Custom-value-resolvers

答案 1 :(得分:1)

您可以基于两个单独的配置创建两个单独的映射器,其中只有一个包含float-to-string映射:

public class InputTypeA { public float Foo { get; set; } }

public class OutputTypeA { public string Foo { get; set; } }

public class InputTypeB { public float Bar { get; set; } }

public class OutputTypeB { public string Bar { get; set; } }

public class Program
{
    public static void Main(string[] args)
    {
        Func<float, string> mapFunc =
            src => String.Format(CultureInfo.InvariantCulture.NumberFormat, "{0:0.00}", src);

        var floatToStringConfig = new MapperConfiguration(cfg =>
        {
            cfg.CreateMap<InputTypeA, OutputTypeA>();
            cfg.CreateMap<float, string>().ConvertUsing(mapFunc);
        });

        var regularConfig = new MapperConfiguration(cfg =>
        {
            cfg.CreateMap<InputTypeB, OutputTypeB>();
        });

        IMapper floatToStringMapper = floatToStringConfig.CreateMapper();
        IMapper regularMapper = regularConfig.CreateMapper();

        var aIn = new InputTypeA() { Foo = 1f };
        var aOut = floatToStringMapper.Map<OutputTypeA>(aIn); 

        Console.WriteLine(aOut.Foo); // prints "1.00"

        var bIn = new InputTypeB() { Bar = 1f };
        var bOut = regularMapper.Map<OutputTypeB>(bIn);

        Console.WriteLine(bOut.Bar); // prints "1"
    }
}