private TN MapInternal <T, TN>(T src, TN dest = default(TN), bool dynamicTrial = false) { 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).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}"); } Register <T, TN>(); return(MapInternal(src, dest, true)); } if (EqualityComparer <TN> .Default.Equals(dest, default(TN))) { PrecompileCollection <T, TN>(CompilationTypes.Source); } else { 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); }