Example #1
0
        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);
        }
Example #2
0
        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);
        }
Example #3
0
        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);
        }
Example #4
0
 private static Dictionary <string, object> MembersDictionary(
     object source,
     ProfileMap profileMap
     ) =>
 profileMap
 .CreateTypeDetails(source.GetType())
 .ReadAccessors.ToDictionary(p => p.Name, p => p.GetMemberValue(source));
Example #5
0
        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;
        }
Example #6
0
        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);
        }
Example #7
0
 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);
        }
Example #9
0
        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);
        }
Example #10
0
        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);
        }
Example #11
0
        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);
        }
Example #12
0
        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);
                }
            }
        }