public bool MapDestinationPropertyToSource(ProfileMap options, TypeDetails sourceType, Type destType, Type destMemberType, string nameToSearch, LinkedList <MemberInfo> resolvers, IMemberConfiguration parent) { var matches = DestinationMemberNamingConvention.SplittingExpression .Matches(nameToSearch) .Cast <Match>() .Select(m => SourceMemberNamingConvention.ReplaceValue(m)) .ToArray(); MemberInfo matchingMemberInfo = null; for (var i = 1; i <= matches.Length; i++) { var snippet = CreateNameSnippet(matches, i); matchingMemberInfo = parent.NameMapper.GetMatchingMemberInfo(sourceType, destType, destMemberType, snippet.First); if (matchingMemberInfo != null) { resolvers.AddLast(matchingMemberInfo); var details = options.CreateTypeDetails(matchingMemberInfo.GetMemberType()); var foundMatch = parent.MapDestinationPropertyToSource(options, details, destType, destMemberType, snippet.Second, resolvers); if (!foundMatch) { resolvers.RemoveLast(); } else { break; } } } return(matchingMemberInfo != null); }
private static object Map( object source, object destination, Type destinationType, ResolutionContext context, ProfileMap profileMap ) { destination ??= ObjectFactory.CreateInstance(destinationType); var destinationTypeDetails = profileMap.CreateTypeDetails(destinationType); foreach (var member in destinationTypeDetails.WriteAccessors) { object sourceMemberValue; try { sourceMemberValue = GetDynamically(member.Name, source); } catch (RuntimeBinderException) { continue; } var destinationMemberValue = context.MapMember( member, sourceMemberValue, destination ); member.SetMemberValue(destination, destinationMemberValue); } return(destination); }
private static Dictionary <string, object> MembersDictionary(object source, ProfileMap profileMap) { var sourceTypeDetails = profileMap.CreateTypeDetails(source.GetType()); var membersDictionary = sourceTypeDetails.PublicReadAccessors.ToDictionary(p => p.Name, p => p.GetMemberValue(source)); return(membersDictionary); }
private static Dictionary <string, object> MembersDictionary( object source, ProfileMap profileMap ) => profileMap .CreateTypeDetails(source.GetType()) .ReadAccessors.ToDictionary(p => p.Name, p => p.GetMemberValue(source));
public bool MapDestinationPropertyToSource(ProfileMap options, TypeDetails sourceType, Type destType, Type destMemberType, string nameToSearch, LinkedList<MemberInfo> resolvers, IMemberConfiguration parent ) { string[] matches = DestinationMemberNamingConvention.SplittingExpression .Matches(nameToSearch) .Cast<Match>() .Select(m => SourceMemberNamingConvention.ReplaceValue(m)) .ToArray(); MemberInfo matchingMemberInfo = null; for (int i = 1; i <= matches.Length; i++) { NameSnippet snippet = CreateNameSnippet(matches, i); matchingMemberInfo = parent.NameMapper.GetMatchingMemberInfo(sourceType, destType, destMemberType, snippet.First); if (matchingMemberInfo != null) { resolvers.AddLast(matchingMemberInfo); var details = options.CreateTypeDetails(matchingMemberInfo.GetMemberType()); var foundMatch = parent.MapDestinationPropertyToSource(options, details, destType, destMemberType, snippet.Second, resolvers); if (!foundMatch) resolvers.RemoveLast(); else break; } } return matchingMemberInfo != null; }
public bool MapDestinationPropertyToSource(ProfileMap options, TypeDetails sourceType, Type destType, Type destMemberType, string nameToSearch, List <MemberInfo> resolvers, IMemberConfiguration parent, bool isReverseMap) { var destinationMemberNamingConvention = isReverseMap ? SourceMemberNamingConvention : DestinationMemberNamingConvention; var sourceMemberNamingConvention = isReverseMap ? DestinationMemberNamingConvention : SourceMemberNamingConvention; var matches = destinationMemberNamingConvention.SplittingExpression ?.Matches(nameToSearch) .Cast <Match>() .Select(m => sourceMemberNamingConvention.ReplaceValue(m)) .ToArray() ?? Array.Empty <string>(); MemberInfo matchingMemberInfo = null; for (var i = 1; i <= matches.Length; i++) { var first = string.Join( sourceMemberNamingConvention.SeparatorCharacter, matches.Take(i).Select(SplitMembers)); var second = string.Join( sourceMemberNamingConvention.SeparatorCharacter, matches.Skip(i).Select(SplitMembers)); matchingMemberInfo = parent.NameMapper.GetMatchingMemberInfo(sourceType, destType, destMemberType, first); if (matchingMemberInfo != null) { resolvers.Add(matchingMemberInfo); var details = options.CreateTypeDetails(matchingMemberInfo.GetMemberType()); var foundMatch = parent.MapDestinationPropertyToSource(options, details, destType, destMemberType, second, resolvers, isReverseMap); if (!foundMatch) { resolvers.RemoveAt(resolvers.Count - 1); } else { break; } } } return(matchingMemberInfo != null); string SplitMembers(string value) => sourceMemberNamingConvention.SplittingExpression.Replace(value, sourceMemberNamingConvention.ReplaceValue); }
public bool MapDestinationPropertyToSource(ProfileMap options, TypeDetails sourceType, Type destType, Type destMemberType, string nameToSearch, LinkedList <MemberInfo> resolvers, IMemberConfiguration parent) { if (map.TryGetValue(new TypePair(sourceType.Type, destType), out var property)) { resolvers.AddLast(property); var memberType = options.CreateTypeDetails(property.PropertyType); if (parent.MapDestinationPropertyToSource(options, memberType, destType, destMemberType, nameToSearch, resolvers)) { return(true); } resolvers.RemoveLast(); } return(false); }
private static TDestination Map <TDestination>(StringDictionary source, TDestination destination, ResolutionContext context, ProfileMap profileMap) { var destTypeDetails = profileMap.CreateTypeDetails(typeof(TDestination)); var members = from name in source.Keys join member in destTypeDetails.PublicWriteAccessors on name equals member.Name select member; object boxedDestination = destination; foreach (var member in members) { var value = context.MapMember(member, source[member.Name], boxedDestination); member.SetMemberValue(boxedDestination, value); } return((TDestination)boxedDestination); }
public static TDestination Map <TSource, TDestination>(TSource source, TDestination destination, ResolutionContext context, ProfileMap profileMap) { var sourceTypeDetails = profileMap.CreateTypeDetails(typeof(TSource)); foreach (var member in sourceTypeDetails.PublicReadAccessors) { object sourceMemberValue; try { sourceMemberValue = member.GetMemberValue(source); } catch (RuntimeBinderException) { continue; } var destinationMemberValue = context.MapMember(member, sourceMemberValue); SetDynamically(member.Name, destination, destinationMemberValue); } return(destination); }
private static TDestination Map <TSource, TDestination>(TSource source, TDestination destination, ResolutionContext context, ProfileMap profileMap) { object boxedDestination = destination; var destinationTypeDetails = profileMap.CreateTypeDetails(typeof(TDestination)); foreach (var member in destinationTypeDetails.PublicWriteAccessors) { object sourceMemberValue; try { sourceMemberValue = GetDynamically(member.Name, source); } catch (RuntimeBinderException) { continue; } var destinationMemberValue = context.MapMember(member, sourceMemberValue, boxedDestination); member.SetMemberValue(boxedDestination, destinationMemberValue); } return((TDestination)boxedDestination); }
private static TDestination Map <TDestination>(StringDictionary source, TDestination destination, ResolutionContext context, ProfileMap profileMap) { var destTypeDetails = profileMap.CreateTypeDetails(typeof(TDestination)); var memberMatches = from member in destTypeDetails.PublicWriteAccessors join key in source.Keys on member.Name equals key.Trim() into matchingKeys where matchingKeys.Any() select new { member, sourceNames = matchingKeys }; object boxedDestination = destination; foreach (var match in memberMatches) { if (match.sourceNames.Count() > 1) { throw new AutoMapperMappingException($"Multiple matching keys were found in the source dictionary for destination member {match.member}.", null, new TypePair(typeof(StringDictionary), typeof(TDestination))); } var value = context.MapMember(match.member, source[match.sourceNames.First()], boxedDestination); match.member.SetMemberValue(boxedDestination, value); } return((TDestination)boxedDestination); }
private static object MapDynamic( StringDictionary source, object boxedDestination, Type destinationType, ResolutionContext context, ProfileMap profileMap ) { boxedDestination ??= ObjectFactory.CreateInstance(destinationType); int matchedCount = 0; foreach (var member in profileMap.CreateTypeDetails(destinationType).WriteAccessors) { var match = MatchSource(member.Name); if (match.Count == 0) { continue; } if (match.Count > 1) { throw new AutoMapperMappingException( $"Multiple matching keys were found in the source dictionary for destination member {member}.", null, new TypePair(typeof(StringDictionary), destinationType) ); } var value = context.MapMember(member, match.Value, boxedDestination); member.SetMemberValue(boxedDestination, value); matchedCount++; } if (matchedCount < source.Count) { MapInnerProperties(); } return(boxedDestination); Match MatchSource(string name) { if (source.TryGetValue(name, out var value)) { return(new Match { Value = value, Count = 1 }); } var matches = source .Where(s => s.Key.Trim() == name) .Select(s => s.Value) .ToArray(); if (matches.Length == 1) { return(new Match { Value = matches[0], Count = 1 }); } return(new Match { Count = matches.Length }); } void MapInnerProperties() { MemberInfo[] innerMembers; foreach (var memberPath in source.Keys.Where(k => k.Contains('.'))) { innerMembers = ReflectionHelper.GetMemberPath(destinationType, memberPath); var innerDestination = GetInnerDestination(); if (innerDestination == null) { continue; } var lastMember = innerMembers[innerMembers.Length - 1]; var value = context.MapMember(lastMember, source[memberPath], innerDestination); lastMember.SetMemberValue(innerDestination, value); } return; object GetInnerDestination() { var currentDestination = boxedDestination; foreach (var member in innerMembers.Take(innerMembers.Length - 1)) { var newDestination = member.GetMemberValue(currentDestination); if (newDestination == null) { if (!member.CanBeSet()) { return(null); } newDestination = ObjectFactory.CreateInstance(member.GetMemberType()); member.SetMemberValue(currentDestination, newDestination); } currentDestination = newDestination; } return(currentDestination); } } }