示例#1
0
        private static object MapDynamic(StringDictionary source, object boxedDestination, Type destinationType, ResolutionContext context, ProfileMap profileMap)
        {
            boxedDestination ??= DelegateFactory.CreateInstance(destinationType);
            int matchedCount = 0;

            foreach (var member in profileMap.CreateTypeDetails(destinationType).PublicWriteAccessors)
            {
                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 = DelegateFactory.CreateInstance(member.GetMemberType());
                            member.SetMemberValue(currentDestination, newDestination);
                        }
                        currentDestination = newDestination;
                    }
                    return(currentDestination);
                }
            }
        }
 public void Test_with_value_object_create_ctor() => DelegateFactory.CreateInstance(typeof(DateTimeOffset)).ShouldBeOfType <DateTimeOffset>();
 public void Create_ctor_should_throw_when_default_constructor_is_missing() =>
 new Action(() => DelegateFactory.CreateInstance(typeof(AssemblyLoadEventArgs)))
 .ShouldThrow <ArgumentException>().Message.ShouldStartWith(typeof(AssemblyLoadEventArgs).FullName);
 public void Test_with_create_ctor() => DelegateFactory.CreateInstance(typeof(DelegateFactoryTests)).ShouldBeOfType <DelegateFactoryTests>();