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); }
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); }