title: Custom object-to-string mapper in AutoMapper
body: <p>Using AutoMapper (v6.2.2, plus <em>AutoMapper.Extensions.Microsoft.DependencyInjection</em>) I want to use my existing system <code>TypeConverter</code> classes to convert from certain data models to strings.</p>
  
  <p>Although the internal <code>MapperRegistry</code> contains a <code>TypeConverterMapper</code> that should be able to do this automatically (<em>without the need for any manual configuration</em> it says <a href="http://automapper.readthedocs.io/en/latest/Custom-type-converters.html" rel="nofollow noreferrer">here</a>), it never gets called as the <code>StringMapper</code> takes precedence when the destination type is a <code>string</code>.</p>
  
  <p>Other (older) answers suggest changing the mapping objects in the <code>MapperRegistry</code>, but it appears that this class has since been made <code>internal</code>.</p>
  
  <p>Can I change the precedence of (or remove) the different in-built mapper classes in AutoMapper?</p>
  
  <hr>
  
  <p>As a workaround, I also tried creating a map in my <code>Profile</code> that would attempt to convert any object to a string using type converters: </p>
  
  <pre><code>private class ApiTypeConverter : ITypeConverter&lt;object, string&gt;
  {
       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);
       }
  }
  </code></pre>
  
  <p>which I configured to be used with:</p>
  
  <pre><code>CreateMap&lt;object, string&gt;().ConvertUsing&lt;ApiTypeConverter&gt;();
  </code></pre>
  
  <p>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:</p>
  
  <pre><code>ForAllMaps((m, e) =&gt; e.ForAllMembers(opt =&gt; opt.Condition(HasConverter))
                        .ConvertUsing&lt;ApiTypeConverter&gt;());
  </code></pre>
  
  <p>However, this is not possible (the <code>ForAllMembers</code> method returns <code>void</code>).</p>
  
  <hr>
  
  <p>As I am using <em>AutoMapper.Extensions.Microsoft.DependencyInjection</em> I was able to use the <code>additionalInitAction</code> parameter to change the mappers:</p>
  
  <pre><code>services.AddAutoMapper(InitAction, GetType().Assembly);
  
  private void InitAction(IMapperConfigurationExpression configuration)
  {
      var mapper = configuration.Mappers.OfType&lt;StringMapper&gt;().First();
      configuration.Mappers.Remove(mapper);
  }
  </code></pre>
  
  <p>This led everything to work as expected, but seems a bit of a hack, as other maps may be relying on the <code>StringMapper</code>.</p>