public TN Map <T, TN>(T src, TN dest = default(TN))
        {
            var srcType  = typeof(T);
            var destType = typeof(TN);
            var cacheKey = CalculateCacheKey(srcType, destType);

            if (CustomMappers.ContainsKey(cacheKey))
            {
                var customTypeMapper = CustomMappers[cacheKey];
                var typeMapper       = customTypeMapper() as ICustomTypeMapper <T, TN>;
                var context          = new DefaultMappingContext <T, TN> {
                    Source = src, Destination = dest
                };
                return(typeMapper.Map(context));
            }


            var mappingService = EqualityComparer <TN> .Default.Equals(dest, default(TN)) ? SourceService : DestinationService;

            if (mappingService.TypeMappers.ContainsKey(cacheKey))
            {
                if (EqualityComparer <T> .Default.Equals(src, default(T)))
                {
                    return(default(TN));
                }

                var mapper = mappingService.TypeMappers[cacheKey] as ITypeMapper <T, TN>;
                return(mapper != null
                    ? mapper.MapTo(src, dest)
                    : default(TN));
            }

            var tCol =
                typeof(T).GetInterfaces()
                .FirstOrDefault(t => t.IsGenericType && t.GetGenericTypeDefinition() == GenericEnumerableType) ??
                (typeof(T).IsGenericType &&
                 typeof(T).GetInterfaces().Any(t => t == typeof(IEnumerable)) ? typeof(T)
                        : null);

            var tnCol = typeof(TN).GetInterfaces()
                        .FirstOrDefault(t => t.IsGenericType && t.GetGenericTypeDefinition() == GenericEnumerableType) ??
                        (typeof(TN).IsGenericType && typeof(TN).GetInterfaces().Any(t => t == typeof(IEnumerable)) ? typeof(TN)
                             : null);

            if (tCol == null || tnCol == null)
            {
                throw new MapNotImplementedException(
                          string.Format("There is no mapping has bee found. Source Type: {0}, Destination Type: {1}",
                                        srcType.FullName, destType.FullName));
            }

            PrecompileCollection <T, TN>();

            // todo: make same signature in both compiled funcs with destination
            var result = (TN)(((EqualityComparer <TN> .Default.Equals(dest, default(TN)))
                ? SourceService.MapCollection(cacheKey).DynamicInvoke(src)
                : DestinationService.MapCollection(cacheKey).DynamicInvoke(src, dest)));

            return(result);
        }
예제 #2
0
        private TN MapInternal <T, TN>(T src, TN dest = default(TN), bool dynamicTrial = false)
        {
            var srcType  = typeof(T);
            var destType = typeof(TN);
            var cacheKey = this.CalculateCacheKey(srcType, destType);

            if (this.CustomMappers.ContainsKey(cacheKey))
            {
                var customTypeMapper = this.CustomMappers[cacheKey];
                var typeMapper       = customTypeMapper() as ICustomTypeMapper <T, TN>;
                var context          = new DefaultMappingContext <T, TN> {
                    Source = src, Destination = dest
                };
                return(typeMapper.Map(context));
            }

            var mappingService = EqualityComparer <TN> .Default.Equals(dest, default(TN)) ? this.SourceService : this.DestinationService;

            if (mappingService.TypeMappers.ContainsKey(cacheKey))
            {
                if (EqualityComparer <T> .Default.Equals(src, default(T)))
                {
                    return(default(TN));
                }

                var mapper = mappingService.TypeMappers[cacheKey] as ITypeMapper <T, TN>;
                return(mapper != null
                    ? mapper.MapTo(src, dest)
                    : default(TN));
            }

            var tCol =
                typeof(T).GetInfo().GetInterfaces()
                .FirstOrDefault(t => t.GetInfo().IsGenericType&& t.GetGenericTypeDefinition() == GenericEnumerableType) ??
                (typeof(T).GetInfo().IsGenericType &&
                 typeof(T).GetInfo().GetInterfaces().Any(t => t == typeof(IEnumerable)) ? typeof(T)
                    : null);

            var tnCol = typeof(TN).GetInfo().GetInterfaces()
                        .FirstOrDefault(t => t.GetInfo().IsGenericType&& t.GetGenericTypeDefinition() == GenericEnumerableType) ??
                        (typeof(TN).GetInfo().IsGenericType&& typeof(TN).GetInfo().GetInterfaces().Any(t => t == typeof(IEnumerable)) ? typeof(TN)
                            : null);

            if (tCol == null || tnCol == null)
            {
                if (dynamicTrial)
                {
                    throw new MapNotImplementedException(
                              $"There is no mapping has been found. Source Type: {srcType.FullName}, Destination Type: {destType.FullName}");
                }
                this.Register <T, TN>();
                return(this.MapInternal(src, dest, true));
            }

            if (EqualityComparer <TN> .Default.Equals(dest, default(TN)))
            {
                this.PrecompileCollection <T, TN>(CompilationTypes.Source);
            }
            else
            {
                this.PrecompileCollection <T, TN>();
            }

            // todo: make same signature in both compiled funcs with destination
            var result = (TN)((EqualityComparer <TN> .Default.Equals(dest, default(TN)))
                ? this.SourceService.MapCollection(cacheKey).DynamicInvoke(src)
                : this.DestinationService.MapCollection(cacheKey).DynamicInvoke(src, dest));

            return(result);
        }