title: Automapper - Access default map function in MapFrom to fallback
body: <p>I'm writing an extension method in order to do translation with Automapper.</p>
  <p>I have some classes :</p>
  <pre class="lang-cs prettyprint-override"><code>public class TranslatableClass : ITranslatable&lt;TranslationClass&gt;
  {
      public string Id { get; set; }
      public string Label { get; set; }
      public string Description { get; set; }
      public List&lt;TranslationClass&gt; Translations { get; set; }
      public string OtherEntityId { get; set; }
      public string OtherEntityLabel { get; set; }
      public List&lt;OtherEntityTranslation&gt; OtherEntityTranslations { get; set; }
  }
  
  public class TranslationClass : ITranslation
  {
      public Guid LanguageId { get; set; }
      public string Label { get; set; }
      public string Description { get; set; }
  }
  
  public class TranslatedClass
  {
      public string Id { get; set; }
      public string Label { get; set; }
      public string Description { get; set; }
      public string OtherEntityLabel { get; set; }
  }
  
  public class OtherEntityTranslation : ITranslation
  {
      public string Label { get; set; }
  
      public Guid LanguageId { get; set; }
  }
  </code></pre>
  <p>I'd like to get an extension method like this one :</p>
  <pre class="lang-cs prettyprint-override"><code>cfg.CreateMap&lt;TranslatableClass, TranslatedClass&gt;()
      .ForMember(t =&gt; t.OtherEntityLabel, opt =&gt; opt.MapFromTranslation(t =&gt; t.OtherEntityTranslations, oet =&gt; oet.Label));
  </code></pre>
  <p>And my extension method looks like this one</p>
  <pre class="lang-cs prettyprint-override"><code>public static void MapFromTranslation&lt;TSource, TDestination, TMember, TTranslation&gt;(this IMemberConfigurationExpression&lt;TSource, TDestination, TMember&gt; opt, Func&lt;TSource, IEnumerable&lt;TTranslation&gt;&gt; getTranslations, Func&lt;TTranslation, string&gt; getValue)
      where TTranslation : ITranslation
  {
      opt.MapFrom((src, _, _, context) =&gt;
      {
          string result = null; // here is the pain point ; I'd like to get the value as if I was automapper 
  
          if (context.Options.Items.TryGetValue(LANGUAGE, out object contextLanguage) &amp;&amp; contextLanguage is Guid languageId)
          {
              var translations = getTranslations(src);
              var translation = translations.FirstOrDefault(t =&gt; t.LanguageId == languageId);
  
              if (translation != null)
              {
                  result = getValue(translation);
              }
          }
  
          return result;
      });
  }
  </code></pre>
  <p>The issue I'm facing is I can't find a nice way to get the default behavior of AutoMapper when I don't have a translation. In this implementation, if I don't find a translation for my language, the value will be null while it should be the value of the source object (which is the default value).</p>
  <p>I try to put PreCondition before the MapFrom but that doesn't map the property so I get null too.</p>
  <p>I can try to get the value from the source object with reflexion but I will lose all the capabilities of Automapper like naming convention and other stuffs.</p>
  <pre class="lang-cs prettyprint-override"><code>public static void MapFromTranslation&lt;TSource, TDestination, TMember, TTranslation&gt;(this IMemberConfigurationExpression&lt;TSource, TDestination, TMember&gt; opt, Func&lt;TSource, IEnumerable&lt;TTranslation&gt;&gt; getTranslations, Func&lt;TTranslation, string&gt; getValue)
      where TTranslation : ITranslation
  {
      var destinationMember = opt.DestinationMember as PropertyInfo;
  
      var source = typeof(TSource);
      var sourceProperty = source.GetProperty(destinationMember.Name);
  
      if (sourceProperty != null)
      {
          opt.MapFrom((src, _, _, context) =&gt;
          {
              string result = sourceProperty.GetValue(src) as string; // Get value from source as if it was the mapper 
  
              if (context.Options.Items.TryGetValue(LANGUAGE, out object contextLanguage) &amp;&amp; contextLanguage is Guid languageId)
              {
                  var translations = getTranslations(src);
  
                  if (translations != null)
                  {
                      var translation = translations.FirstOrDefault(t =&gt; t.LanguageId == languageId);
  
                      if (translation != null)
                      {
                          var value = getValue(translation);
                          if (!String.IsNullOrWhiteSpace(value))
                          {
                              result = value;
                          }
                      }
                  }
              }
  
              return result;
          });
      }
      else
      {
          throw new Exception($&quot;Can't map property {opt.DestinationMember.Name} from {source.Name}&quot;);
      }
  }
  </code></pre>