Using AutoMapper (v6.2.2, plus AutoMapper.Extensions.Microsoft.DependencyInjection) I want to use my existing system TypeConverter classes to convert from certain data models to strings.
Although the internal MapperRegistry contains a TypeConverterMapper that should be able to do this automatically (without the need for any manual configuration it says here), it never gets called as the StringMapper takes precedence when the destination type is a string.
Other (older) answers suggest changing the mapping objects in the MapperRegistry, but it appears that this class has since been made internal.
Can I change the precedence of (or remove) the different in-built mapper classes in AutoMapper?
As a workaround, I also tried creating a map in my Profile that would attempt to convert any object to a string using type converters:
private class ApiTypeConverter : ITypeConverter<object, string>
{
public string Convert(object source, string destination, ResolutionContext context)
{
TypeConverter sourceTypeConverter = TypeDescriptor.GetConverter(source.GetType());
if (sourceTypeConverter.CanConvertTo(typeof(string)))
{
return (string)sourceTypeConverter.ConvertTo(source, typeof(string));
}
return default(string);
}
}
which I configured to be used with:
CreateMap<object, string>().ConvertUsing<ApiTypeConverter>();
But this has not worked as expected yet either. Ideally I'd only do this for members which could be converted using a condition, something like:
ForAllMaps((m, e) => e.ForAllMembers(opt => opt.Condition(HasConverter))
.ConvertUsing<ApiTypeConverter>());
However, this is not possible (the ForAllMembers method returns void).
As I am using AutoMapper.Extensions.Microsoft.DependencyInjection I was able to use the additionalInitAction parameter to change the mappers:
services.AddAutoMapper(InitAction, GetType().Assembly);
private void InitAction(IMapperConfigurationExpression configuration)
{
var mapper = configuration.Mappers.OfType<StringMapper>().First();
configuration.Mappers.Remove(mapper);
}
This led everything to work as expected, but seems a bit of a hack, as other maps may be relying on the StringMapper.