@@ -9,6 +9,8 @@ namespace AutoMapper.Execution
99 using static Expression ;
1010 using static ExpressionBuilder ;
1111 using Internal ;
12+ using AutoMapper . Configuration ;
13+
1214 public class TypeMapPlanBuilder
1315 {
1416 private static readonly MethodInfo CreateProxyMethod = typeof ( ObjectFactory ) . GetStaticMethod ( nameof ( ObjectFactory . CreateInterfaceProxy ) ) ;
@@ -33,7 +35,7 @@ public TypeMapPlanBuilder(IGlobalConfiguration configurationProvider, TypeMap ty
3335 public LambdaExpression CreateMapperLambda ( HashSet < TypeMap > typeMapsPath )
3436 {
3537 var parameters = new [ ] { Source , _initialDestination , ContextParameter } ;
36- var customExpression = TypeConverter ( parameters ) ?? ( _typeMap . CustomMapFunction ?? _typeMap . CustomMapExpression ) ? . ConvertReplaceParameters ( parameters ) ;
38+ var customExpression = _typeMap . TypeConverter ? . GetExpression ( parameters ) ;
3739 if ( customExpression != null )
3840 {
3941 return Lambda ( customExpression , parameters ) ;
@@ -61,16 +63,6 @@ public LambdaExpression CreateMapperLambda(HashSet<TypeMap> typeMapsPath)
6163 statements . Add ( mapperFunc ) ;
6264 variables . Add ( _destination ) ;
6365 return Lambda ( Block ( variables , statements ) , parameters ) ;
64- Expression TypeConverter ( ParameterExpression [ ] parameters )
65- {
66- if ( _typeMap . TypeConverterType == null )
67- {
68- return null ;
69- }
70- var converterInterfaceType = typeof ( ITypeConverter < , > ) . MakeGenericType ( _typeMap . SourceType , DestinationType ) ;
71- var converter = ServiceLocator ( _typeMap . TypeConverterType ) ;
72- return Call ( ToType ( converter , converterInterfaceType ) , "Convert" , parameters ) ;
73- }
7466 static void Clear ( ref HashSet < TypeMap > typeMapsPath )
7567 {
7668 if ( typeMapsPath == null )
@@ -423,7 +415,6 @@ static Expression CustomMapExpression(Expression mapFrom, Type destinationProper
423415 }
424416 }
425417 private Expression GetCustomSource ( MemberMap memberMap ) => memberMap . IncludedMember ? . Variable ?? Source ;
426- private static Expression ServiceLocator ( Type type ) => Call ( ContextParameter , ContextCreate , Constant ( type ) ) ;
427418 private Expression BuildResolveCall ( MemberMap memberMap , Expression source , Expression destValueExpr )
428419 {
429420 var typeMap = memberMap . TypeMap ;
@@ -466,4 +457,40 @@ AutoMapperConfigurationException BuildExceptionMessage()
466457 => new AutoMapperConfigurationException ( $ "Cannot find a source member to pass to the value converter of type { valueConverterConfig . ConcreteType . FullName } . Configure a source member to map from.") ;
467458 }
468459 }
460+ public abstract class TypeConverter
461+ {
462+ public abstract Expression GetExpression ( ParameterExpression [ ] parameters ) ;
463+ public virtual void CloseGenerics ( ITypeMapConfiguration openMapConfig , TypePair closedTypes ) { }
464+ }
465+ public class LambdaTypeConverter : TypeConverter
466+ {
467+ public LambdaTypeConverter ( LambdaExpression lambda ) => Lambda = lambda ;
468+ public LambdaExpression Lambda { get ; }
469+ public override Expression GetExpression ( ParameterExpression [ ] parameters ) => Lambda . ConvertReplaceParameters ( parameters ) ;
470+ }
471+ public class ClassTypeConverter : TypeConverter
472+ {
473+ public ClassTypeConverter ( TypePair types , Type converterType , Type converterInterface )
474+ {
475+ Types = types ;
476+ ConverterType = converterType ;
477+ ConverterInterface = converterInterface ;
478+ }
479+ public ClassTypeConverter ( TypePair types , Type converterType ) : this ( types , converterType , types . ContainsGenericParameters ? null : types . ITypeConverter ( ) )
480+ {
481+ }
482+ public TypePair Types { get ; }
483+ public Type ConverterType { get ; private set ; }
484+ public Type ConverterInterface { get ; private set ; }
485+ public override Expression GetExpression ( ParameterExpression [ ] parameters ) =>
486+ Call ( ToType ( ServiceLocator ( ConverterType ) , ConverterInterface ) , "Convert" , parameters ) ;
487+ public override void CloseGenerics ( ITypeMapConfiguration openMapConfig , TypePair closedTypes )
488+ {
489+ var typeParams = ( openMapConfig . SourceType . IsGenericTypeDefinition ? closedTypes . SourceType . GenericTypeArguments : Type . EmptyTypes )
490+ . Concat ( openMapConfig . DestinationType . IsGenericTypeDefinition ? closedTypes . DestinationType . GenericTypeArguments : Type . EmptyTypes ) ;
491+ var neededParameters = ConverterType . GenericParametersCount ( ) ;
492+ ConverterType = ConverterType . MakeGenericType ( typeParams . Take ( neededParameters ) . ToArray ( ) ) ;
493+ ConverterInterface = closedTypes . ITypeConverter ( ) ;
494+ }
495+ }
469496}
0 commit comments