J'ai deux classes, un ViewModel et un Dto, qui sont fondamentalement identiques sauf que le Dto a un champ 'readonly long ? Phone;' alors que le ViewModel a une propriété 'string Phone { get ; set ; }'.
Le seul moyen que j'ai trouvé pour faire fonctionner AutoMapper est de changer la propriété ViewModel en une propriété d'appui :
public long? Phone { get; set; }
public string PhoneNumberString
{
get
{
var srv = DependencyResolver.Current.GetService<IPhoneNumberService>();
return srv.GetFormattedPhoneNumber(Phone);
}
set
{
var srv = DependencyResolver.Current.GetService<IPhoneNumberService>();
Phone = srv.GetLongPhoneNumber(value);
}
}
Ensuite, dans AutoMapper, il y a une ligne gigantesque pour appeler le constructeur :
Mapper.Initialize(cfg =>
{
cfg.CreateMap<MyViewModel, MyDto>()
.ConstructUsing(src => new MyDto(
src.Phone
/* ...Some ~30 other parameters here... */))
.ReverseMap();
});
...Il doit y avoir une meilleure façon de procéder ? J'ai essayé ceci :
.ForSourceMember(x => x.PhoneNumberString, opt => opt.DoNotValidate())
et
.ForMember(x => x.PhoneNumberString, opt => opt.Ignore())
et
.ForMember(viewModel => viewModel.Phone, options => options.MapFrom<PhoneNumberResolver>());//PhoneNumberResolver implements IValueResolver<ProspectMaintenanceViewModel, ProspectMaintenanceDto, long?>
Qui donnent tous 'Core.DTO.MyDto needs to have a constructor with 0 args or only optional args' lorsqu'ils essaient de mapper, et :
.ForMember(dest => dest.Phone, opt => opt.MapFrom(src => 5))
Ce qui donne 'System.ArgumentException : 'Expression must be writeable' lors de la configuration d'AutoMapper.
Existe-t-il un moyen de faire comprendre à AutoMapper qu'il peut ignorer PhoneNumberString (ou, mieux encore, un moyen de le faire convertir long ? en string pour que je n'aie pas besoin de la propriété backing) sans avoir à utiliser le constructeur du dto ?
Existe-t-il une raison particulière pour laquelle votre DTO n'a pas de constructeur par défaut ?
Tous mes champs sont en lecture seule, ce qui me permet d'inclure un constructeur qui modifie (par exemple, "Description = description ?.Trim() ;") et valide (par exemple, "if (Phone.HasValue && Phone.ToString().Length != 10) throw ...") les paramètres. De cette façon, je peux m'assurer que le Dto, étant un objet valeur, est toujours dans un état valide.