我有很多 DTO 必须映射到我的域对象。一般来说,与货币价值的映射需要应用四舍五入规则。这适用于 95% 以上的情况,但我有一些数据需要不同的舍入规则。我计划做下一个:
1) 为一般舍入规则创建一个 ITypeConverter,该规则适用于此类型转换的默认值。
2)为特殊的舍入情况创建一个ValueResolver,并在成员映射中指定它们的用途。
我创建了一个测试用例来尝试我的方法,但是在对特殊情况应用 ValueResolver 之后,AutoMapper 使用 TypeConverter 来获取最终值,使用一般规则。
这是错误的做法??可能是我错过了什么?
然后是测试用例:
[TestFixture]
public class RoundingTests
{
public class MoneyConverter : ITypeConverter<decimal, decimal>
{
public decimal Convert(ResolutionContext context)
{
return Math.Round((decimal)context.SourceValue, 2, MidpointRounding.AwayFromZero);
}
}
public class Money12Resolver : ValueResolver<decimal, decimal>
{
protected override decimal ResolveCore(decimal source)
{
return Math.Round(source, 12, MidpointRounding.AwayFromZero);
}
}
public class PercentResolver : ValueResolver<decimal, decimal>
{
protected override decimal ResolveCore(decimal source)
{
return Math.Round(source, 4, MidpointRounding.AwayFromZero);
}
}
internal class Source
{
public decimal Price { get; set; }
public decimal Percent { get; set; }
public decimal Prorate { get; set; }
}
internal class Destination
{
public decimal Price { get; set; }
public decimal Percent { get; set; }
public decimal Prorate { get; set; }
}
[Test]
public void MappingTest()
{
Mapper.CreateMap<decimal, decimal>().ConvertUsing<MoneyConverter>();
Mapper.CreateMap<Source, Destination>()
.ForMember(d => d.Percent, o => o.ResolveUsing<PercentResolver>().FromMember(s => s.Percent))
.ForMember(d => d.Prorate, o => o.ResolveUsing<Money12Resolver>().FromMember(s => s.Prorate));
Mapper.AssertConfigurationIsValid();
var source = new Source
{
Price = 12345.6789m,
Percent = 0.123456m,
Prorate = 123.123451234512345m
};
var convertion = Mapper.Map<Destination>(source);
Assert.That(convertion, Is.Not.Null);
Assert.That(convertion.Price, Is.EqualTo(12345.68m));
Assert.That(convertion.Percent, Is.EqualTo(0.1235m));
Assert.That(convertion.Prorate, Is.EqualTo(123.123451234512m));
}
}
测试结果:
Expected: 0.1235m
But was: 0.12m