public void Map <TSource, TTarget>(TSource source, out TTarget target,
                                           ReferenceTracking referenceTracking = null) where TTarget : struct
        {
            if (referenceTracking == null)
            {
                referenceTracking = new ReferenceTracking();
            }

            //Non è il massimo: salta la funzione di map principale
            // e non tiene in cache le espressioni generate.
            Type sourceType = typeof(TSource);
            Type targetType = typeof(TTarget);

            var mapping = this.MappingConfiguration[sourceType, targetType];

            if (mapping.MappingExpression.Parameters[0].Type == typeof(ReferenceTracking))
            {
                var method = (Func <ReferenceTracking, TSource, TTarget, TTarget>)mapping.MappingExpression.Compile();
                target = method.Invoke(referenceTracking, source, new TTarget());
            }
            else
            {
                var method = (Func <TSource, TTarget>)mapping.MappingExpression.Compile();
                target = method.Invoke(source);
            }
        }
Beispiel #2
0
        //public class AbstractTypeMappingCrawler
        //{
        //    public IMapping GetMapping<TSource, TTarget>( TSource source, TTarget target, IMapping mapping )
        //    {
        //        Type mappingSourceType = null;
        //        Type mappingTargetType = null;

        //        if( mapping is TypeMapping typeMapping )
        //        {
        //            mappingSourceType = typeMapping.TypePair.SourceType;
        //            mappingTargetType = typeMapping.TypePair.TargetType;
        //        }
        //        else if( mapping is MemberMapping memberMapping &&
        //            memberMapping.MappingResolution == MappingResolution.RESOLVED_BY_CONVENTION )
        //        {
        //            var memberTypeMapping = memberMapping.MemberTypeMapping;
        //            mappingSourceType = memberTypeMapping.TypePair.SourceType;
        //            mappingTargetType = memberTypeMapping.TypePair.TargetType;
        //        }

        //        if( (mappingSourceType.IsInterface || mappingSourceType.IsAbstract) &&
        //            (mappingTargetType.IsInterface || mappingTargetType.IsAbstract) )
        //        {
        //            return this.MappingConfiguration[ source.GetType(), target.GetType() ];
        //        }

        //        if( mappingSourceType.IsInterface || mappingSourceType.IsAbstract )
        //            return this.MappingConfiguration[ source.GetType(), mappingTargetType ];

        //        if( mappingTargetType.IsInterface || mappingTargetType.IsAbstract )
        //            return this.MappingConfiguration[ mappingSourceType, target.GetType() ];
        //    }
        //}

        internal void Map <TSource, TTarget>(TSource source, TTarget target,
                                             ReferenceTracking referenceTracking, IMapping mapping)
        {
            //in order to manage inheritance at runtime here
            //we check if a mapping has been defined and if it has not
            //we create a specific mapping at runtime.
            //A new mapping is created only if no compatible mapping is already available
            //for concrete classes. If a mapping for the interfaces is found, it is used.

            //---runtime checks for abstract classes and interfaces.

            IMapping CheckResolveAbstractMapping(Type sourceType, Type targetType)
            {
                if ((sourceType.IsInterface || sourceType.IsAbstract) &&
                    (targetType.IsInterface || targetType.IsAbstract))
                {
                    return(this.MappingConfiguration[source.GetType(), target.GetType()]);
                }

                if (sourceType.IsInterface || sourceType.IsAbstract)
                {
                    return(this.MappingConfiguration[source.GetType(), targetType]);
                }

                if (targetType.IsInterface || targetType.IsAbstract)
                {
                    return(this.MappingConfiguration[sourceType, target.GetType()]);
                }

                return(mapping);
            };

            if (mapping is TypeMapping typeMapping)
            {
                var mappingSourceType = typeMapping.TypePair.SourceType;
                var mappingTargetType = typeMapping.TypePair.TargetType;

                mapping = CheckResolveAbstractMapping(mappingSourceType, mappingTargetType);
            }
            else if (mapping is MemberMapping memberMapping)
            {
                if (memberMapping.MappingResolution == MappingResolution.RESOLVED_BY_CONVENTION)
                {
                    var memberTypeMapping = memberMapping.MemberTypeMapping;
                    var mappingSourceType = memberTypeMapping.TypePair.SourceType;
                    var mappingTargetType = memberTypeMapping.TypePair.TargetType;

                    mapping = CheckResolveAbstractMapping(mappingSourceType, mappingTargetType);
                }
            }
            //---ends of runtime checks for abstract classes and interfaces

            try
            {
                mapping.MappingFunc.Invoke(referenceTracking, source, target);
            }
            catch (Exception ex)
            {
            }
        }
Beispiel #3
0
        /// <summary>
        /// Maps from <param name="source"/> to the existing instance <paramref name="target"/>
        /// Let's you reuse an existing <see cref="ReferenceTracking"/> cache.
        /// /// </summary>
        /// <typeparam name="TSource">Type of the source instance.</typeparam>
        /// <typeparam name="TTarget">Type of the target instance.</typeparam>
        /// <param name="source">The source instance from which the values are read.</param>
        /// <param name="target">The target instance to which the values are written.</param>
        public void Map <TSource, TTarget>(TSource source, TTarget target,
                                           ReferenceTracking referenceTracking = null,
                                           ReferenceBehaviors refBehavior      = ReferenceBehaviors.USE_TARGET_INSTANCE_IF_NOT_NULL)
            where TTarget : class
        {
            if (source == null)
            {
                target = null;
                return;
            }

            if (referenceTracking == null)
            {
                referenceTracking = new ReferenceTracking();
            }

            Type sourceType = source.GetType();
            Type targetType = target.GetType();

            referenceTracking.Add(source, targetType, target);

            var mapping = this.MappingConfiguration[sourceType, targetType];

            //since we pass an existing target instance to map onto;
            //by default we use all of the existing instances we found on the target
            mapping.ReferenceBehavior = refBehavior;

            this.Map(source, target, referenceTracking, mapping);
        }
        /// <summary>
        /// Maps from <param name="source"/> to the existing instance <paramref name="target"/>
        /// Let's you reuse an existing <see cref="ReferenceTracking"/> cache.
        /// /// </summary>
        /// <typeparam name="TSource">Type of the source instance.</typeparam>
        /// <typeparam name="TTarget">Type of the target instance.</typeparam>
        /// <param name="source">The source instance from which the values are read.</param>
        /// <param name="target">The target instance to which the values are written.</param>
        public void Map <TSource, TTarget>(TSource source, TTarget target,
                                           ReferenceTracking referenceTracking = null) where TTarget : class
        {
            if (referenceTracking == null)
            {
                referenceTracking = new ReferenceTracking();
            }

            Type sourceType = source.GetType();
            Type targetType = target.GetType();

            referenceTracking.Add(source, targetType, target);

            var mapping = this.MappingConfiguration[sourceType, targetType];

            this.Map(source, target, referenceTracking, mapping);
        }
 internal void Map <TSource, TTarget>(TSource source, TTarget target,
                                      ReferenceTracking referenceTracking, IMapping mapping)
 {
     mapping.MappingFunc.Invoke(referenceTracking, source, target);
 }
        internal void Map <TSource, TTarget>(TSource source, TTarget target,
                                             ReferenceTracking referenceTracking, IMapping mapping)
        {
            //in order to manage inheritance at runtime here
            //we check if a mapping has been defined and if it has not
            //we create a specific mapping at runtime.
            //A new mapping is created only if no compatible mapping is already available
            //for concrete classes. If a mapping for the interfaces is found, it is used.

            Type        mappingSourceType;
            Type        mappingTargetType;
            TypeMapping typeMapping = null;

            //---runtime checks for abstract classes and interfaces.

            //TODO: CREATE A CENTRALIZED CRAWLER/SELECTOR THAT IS ABLE
            //TO CHOOSE IF TO USE A MEMBER MAPPING OR A TYPE MAPPING
            //AND IS ABLE TO DEAL WITH INTERFACES AND ABSTRACT CLASSES:
            //THIS CRAWLER WOULD AVOID US THE NEED TO MANUALLY CRAWL
            //UP THE TYPEMAPPING IN THE MEMBER MAPPPING CLASS AND
            //SIMPLIFIES THE CODE IN A LOT OF PLACES (HERE INCLUDED)

            if (mapping is TypeMapping)
            {
                typeMapping = ((TypeMapping)mapping);

                mappingSourceType = typeMapping.TypePair.SourceType;
                mappingTargetType = typeMapping.TypePair.TargetType;

                if ((mappingSourceType.IsInterface || mappingSourceType.IsAbstract) &&
                    (mappingTargetType.IsInterface || mappingTargetType.IsAbstract))
                {
                    mapping = this.MappingConfiguration[source.GetType(), target.GetType()];
                }
                else if (mappingSourceType.IsInterface || mappingSourceType.IsAbstract)
                {
                    mapping = this.MappingConfiguration[source.GetType(), mappingTargetType];
                }
                else if (mappingTargetType.IsInterface || mappingTargetType.IsAbstract)
                {
                    mapping = this.MappingConfiguration[mappingSourceType, target.GetType()];
                }
            }
            else if (mapping is MemberMapping)
            {
                var m = (MemberMapping)mapping;
                if (m.MappingResolution == MappingResolution.RESOLVED_BY_CONVENTION)
                {
                    typeMapping       = m.MemberTypeMapping;
                    mappingSourceType = typeMapping.TypePair.SourceType;
                    mappingTargetType = typeMapping.TypePair.TargetType;

                    if ((mappingSourceType.IsInterface || mappingSourceType.IsAbstract) &&
                        (mappingTargetType.IsInterface || mappingTargetType.IsAbstract))
                    {
                        mapping = this.MappingConfiguration[source.GetType(), target.GetType()];
                    }
                    else if (mappingSourceType.IsInterface || mappingSourceType.IsAbstract)
                    {
                        mapping = this.MappingConfiguration[source.GetType(), mappingTargetType];
                    }
                    else if (mappingTargetType.IsInterface || mappingTargetType.IsAbstract)
                    {
                        mapping = this.MappingConfiguration[mappingSourceType, target.GetType()];
                    }
                }
            }
            //---ends of runtime checks for abstract classes and interfaces

            mapping.MappingFunc.Invoke(referenceTracking, source, target);
        }