Специальная обработка свойств float в некоторых, но не во всех отображениях AutoMapper
Я только что начал с AutoMapper в C#. Я успешно создал такое отображение:
Mapper.CreateMap<InputTypeA, OutputTypeA>()
Я также нашел способ добавить некоторую логику к определенным свойствам, например, форматирование даты (в InputTypeA) в строку в определенном формате (в OutputTypeA).
.ForMember(
dest => dest.MyDateProperty,
opt => opt.ResolveUsing(
src => String.Format("{0:yyyy-MM-dd}", src.MyDateProperty)));
теперь мне нужно сделать то же самое для ряда свойств float, но мне интересно, есть ли короткий / простой способ сделать это, кроме копирования фрагмента кода, подобного приведенному выше для каждого свойства это должно следовать этому правилу.
я обнаружил, что могу создать новую карту, как это для отображения поплавков в строки:
Mapper.CreateMap<float,string>()
.ConvertUsing(src =>
String.Format(CultureInfo.InvariantCulture.NumberFormat, "{0:0.00}", src));
это работает, но слишком общий, потому что у меня также есть сопоставление для другого типа (назовем его InputTypeB), который также содержит свойства float, которые нужно рассматривать по-разному.
Mapper.CreateMap<InputTypeB, OutputTypeB>()
как я могу сделать отображение float-to-string частью только первого отображения?
2 ответов
вы можете создать два отдельных картографа на основе двух отдельных конфигураций, только одна из которых включает отображение 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"
}
}
вы можете создавать пользовательские преобразователи значений для каждого случая, который вам нужно обработать. Затем примените их к соответствующим членам в ваших сопоставлениях.
в качестве примера мне нужно сопоставить от 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));
Теперь решатель можно применять везде, где он есть необходимый.
Docs:https://github.com/AutoMapper/AutoMapper/wiki/Custom-value-resolvers