99namespace AutoMapper . Configuration
1010{
1111 using static Expression ;
12+ using static Execution . ExpressionBuilder ;
1213 using Execution ;
1314 [ EditorBrowsable ( EditorBrowsableState . Never ) ]
1415 public interface ITypeMapConfiguration
@@ -456,18 +457,16 @@ public TMappingExpression ConstructUsing(Func<TSource, ResolutionContext, TDesti
456457 public void ConvertUsing ( Type typeConverterType )
457458 {
458459 HasTypeConverter = true ;
459- TypeMapActions . Add ( tm => tm . TypeConverterType = typeConverterType ) ;
460+ TypeMapActions . Add ( tm => tm . TypeConverter = new ClassTypeConverter ( Types , typeConverterType ) ) ;
460461 }
461462
462463 public void ConvertUsing ( Func < TSource , TDestination , TDestination > mappingFunction )
463464 {
464465 HasTypeConverter = true ;
465466 TypeMapActions . Add ( tm =>
466467 {
467- Expression < Func < TSource , TDestination , ResolutionContext , TDestination > > expr =
468- ( src , dest , ctxt ) => mappingFunction ( src , dest ) ;
469-
470- tm . CustomMapFunction = expr ;
468+ Expression < Func < TSource , TDestination , ResolutionContext , TDestination > > expr = ( src , dest , ctxt ) => mappingFunction ( src , dest ) ;
469+ tm . TypeConverter = new LambdaTypeConverter ( expr ) ;
471470 } ) ;
472471 }
473472
@@ -476,10 +475,8 @@ public void ConvertUsing(Func<TSource, TDestination, ResolutionContext, TDestina
476475 HasTypeConverter = true ;
477476 TypeMapActions . Add ( tm =>
478477 {
479- Expression < Func < TSource , TDestination , ResolutionContext , TDestination > > expr =
480- ( src , dest , ctxt ) => mappingFunction ( src , dest , ctxt ) ;
481-
482- tm . CustomMapFunction = expr ;
478+ Expression < Func < TSource , TDestination , ResolutionContext , TDestination > > expr = ( src , dest , ctxt ) => mappingFunction ( src , dest , ctxt ) ;
479+ tm . TypeConverter = new LambdaTypeConverter ( expr ) ;
483480 } ) ;
484481 }
485482
@@ -488,7 +485,7 @@ public void ConvertUsing(Func<TSource, TDestination, ResolutionContext, TDestina
488485 public void ConvertUsing < TTypeConverter > ( ) where TTypeConverter : ITypeConverter < TSource , TDestination >
489486 {
490487 HasTypeConverter = true ;
491- TypeMapActions . Add ( tm => tm . TypeConverterType = typeof ( TTypeConverter ) ) ;
488+ TypeMapActions . Add ( tm => tm . TypeConverter = new ClassTypeConverter ( Types , typeof ( TTypeConverter ) , typeof ( ITypeConverter < TSource , TDestination > ) ) ) ;
492489 }
493490
494491 public TMappingExpression ForCtorParam ( string ctorParamName , Action < ICtorParamConfigurationExpression < TSource > > paramOptions )
@@ -525,7 +522,11 @@ public TMappingExpression IgnoreAllSourcePropertiesWithAnInaccessibleSetter()
525522 public void ConvertUsing ( Expression < Func < TSource , TDestination > > mappingFunction )
526523 {
527524 HasTypeConverter = true ;
528- TypeMapActions . Add ( tm => tm . CustomMapExpression = mappingFunction ) ;
525+ TypeMapActions . Add ( tm =>
526+ {
527+ tm . CustomMapExpression = mappingFunction ;
528+ tm . TypeConverter = new LambdaTypeConverter ( mappingFunction ) ;
529+ } ) ;
529530 }
530531
531532 public TMappingExpression AsProxy ( )
@@ -538,4 +539,35 @@ public TMappingExpression AsProxy()
538539 return this as TMappingExpression ;
539540 }
540541 }
542+ public class LambdaTypeConverter : TypeConverter
543+ {
544+ public LambdaTypeConverter ( LambdaExpression lambda ) => Lambda = lambda ;
545+ public LambdaExpression Lambda { get ; }
546+ public override Expression GetExpression ( ParameterExpression [ ] parameters ) => Lambda . ConvertReplaceParameters ( parameters ) ;
547+ }
548+ public class ClassTypeConverter : TypeConverter
549+ {
550+ public ClassTypeConverter ( TypePair types , Type converterType , Type converterInterface )
551+ {
552+ Types = types ;
553+ ConverterType = converterType ;
554+ ConverterInterface = converterInterface ;
555+ }
556+ public ClassTypeConverter ( TypePair types , Type converterType ) : this ( types , converterType , types . ContainsGenericParameters ? null : types . ITypeConverter ( ) )
557+ {
558+ }
559+ public TypePair Types { get ; }
560+ public Type ConverterType { get ; private set ; }
561+ public Type ConverterInterface { get ; private set ; }
562+ public override Expression GetExpression ( ParameterExpression [ ] parameters ) =>
563+ Call ( ToType ( ServiceLocator ( ConverterType ) , ConverterInterface ) , "Convert" , parameters ) ;
564+ public override void CloseGenerics ( ITypeMapConfiguration openMapConfig , TypePair closedTypes )
565+ {
566+ var typeParams = ( openMapConfig . SourceType . IsGenericTypeDefinition ? closedTypes . SourceType . GenericTypeArguments : Type . EmptyTypes )
567+ . Concat ( openMapConfig . DestinationType . IsGenericTypeDefinition ? closedTypes . DestinationType . GenericTypeArguments : Type . EmptyTypes ) ;
568+ var neededParameters = ConverterType . GenericParametersCount ( ) ;
569+ ConverterType = ConverterType . MakeGenericType ( typeParams . Take ( neededParameters ) . ToArray ( ) ) ;
570+ ConverterInterface = closedTypes . ITypeConverter ( ) ;
571+ }
572+ }
541573}
0 commit comments