internal static ComplexMapResult <TSource, TTarget> Create <TSource, TSourceProperty, TTarget, TTargetProperty>( PropertyInfo sourceProperty, PropertyInfo targetProperty, Dictionary <SourceToTargetMap, MapTracker> typeMappings, PropertyConfig <TSourceProperty, TTargetProperty> config) where TSource : class where TTarget : class where TSourceProperty : class where TTargetProperty : class { var createMapFunc = typeof(MappingBuilder).GetMethod(nameof(MappingBuilder.CreateMap), BindingFlags.Static | BindingFlags.NonPublic) .MakeGenericMethod(sourceProperty.PropertyType, targetProperty.PropertyType); var mapFuncResult = (ComplexMapResult <TSourceProperty, TTargetProperty>)createMapFunc .Invoke(null, new object[] { sourceProperty.PropertyType, targetProperty.PropertyType, config.MappingConfiguration, typeMappings }); var mapFunc = mapFuncResult.MappingFunc; var constructor = PropertyAccess.GetDefaultConstructor <TTargetProperty>(); var sourcePropertyGetter = PropertyAccess.CreateGetter <TSource, TSourceProperty>(sourceProperty); var setter = PropertyAccess.CreateSetter <TTarget, TTargetProperty>(targetProperty); var requiresReferenceTracking = mapFuncResult.ReferenceTrackingTypes; if (!config.MappingConfiguration.ReferenceTrackingEnabled || requiresReferenceTracking.Any(x => x.Source == sourceProperty.PropertyType && x.Target == targetProperty.PropertyType)) { return(new ComplexMapResult <TSource, TTarget>(MappingFuncWithReferenceTracking(sourcePropertyGetter, setter, constructor, mapFunc), requiresReferenceTracking)); } return(new ComplexMapResult <TSource, TTarget>( MappingWithoutReferenceTracking(sourcePropertyGetter, setter, constructor, mapFunc), requiresReferenceTracking)); }
internal static Action <TSource, TTarget, ReferenceTracker> Create <TSource, TSourceProperty, TTarget, TTargetProperty>( PropertyInfo sourceProperty, PropertyInfo targetProperty, PropertyConfig <TSourceProperty, TTargetProperty> cfg) { var getter = PropertyAccess.CreateGetter <TSource, TSourceProperty>(sourceProperty); var setter = PropertyAccess.CreateSetter <TTarget, TTargetProperty>(targetProperty); Action <TSource, TTarget, ReferenceTracker> Func(Func <TSource, TSourceProperty> sourceGetter, Action <TTarget, TTargetProperty> propertySetter, Func <TSourceProperty, TTargetProperty> convert) => (source, target, _) => propertySetter(target, convert(sourceGetter(source))); return(Func(getter, setter, cfg.Converter.Convert)); }
internal static Action <TSource, TTarget, ReferenceTracker> Create <TSource, TTarget, TSourceProperty, TTargetProperty, TSourceInstanceType, TTargetInstanceType>(PropertyInfo sourceProperty, PropertyInfo targetProperty, Dictionary <SourceToTargetMap, MapTracker> existingMaps) where TSourceProperty : class, IList <TSourceInstanceType> where TTargetProperty : class, IList <TTargetInstanceType> { var sourceInstanceType = typeof(TSourceInstanceType); var sourceGetter = PropertyAccess.CreateGetter <TSource, TSourceProperty>(sourceProperty); var targetSetter = PropertyAccess.CreateSetter <TTarget, TTargetProperty>(targetProperty); Func <TSourceInstanceType, TTargetInstanceType> convertFunc; if (sourceInstanceType.IsPrimitive || sourceInstanceType == typeof(string) || sourceInstanceType.IsValueType) { var converter = IdentityPropertyConverter <TSourceInstanceType> .Instance as IPropertyConverter <TSourceInstanceType, TTargetInstanceType>; convertFunc = converter.Convert; } else { var mapping = Mapping <TSourceInstanceType, TTargetInstanceType> .Auto(); convertFunc = mapping.Clone; } void Map(TSource source, TTarget target, ReferenceTracker tracker) { var sourceList = sourceGetter(source); var result = new List <TTargetInstanceType>(sourceList.Count); for (int i = 0; i < sourceList.Count; i++) { var item = sourceList[i]; result.Add(convertFunc(item)); } targetSetter(target, result as TTargetProperty); } return(Map); }