Ejemplo n.º 1
0
        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));
        }