Skip to content

Fix issue108 #109

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 5 commits into from
Closed

Fix issue108 #109

wants to merge 5 commits into from

Conversation

4E-69-63-6B-20-42-6F-73
Copy link

Fix for issue #108

@BlaiseD
Copy link
Member

BlaiseD commented Mar 2, 2021

Sorry I misunderstood the issue. For some reason I thought the problem was with mapping anonymous types.

We don't want to make exceptions for specific methods like Select. The solution would be to map the NewExpression and the MemberInitExpression. e.g. In ExpressionMapper.cs

            protected override Expression VisitNew(NewExpression node)
            {
                if (node.Type == _oldParam.Type)
                    return Expression.New(_newParam.Type);

                return base.VisitNew(node);
            }

            protected override Expression VisitMemberInit(MemberInitExpression node)
            {
                if (node.Type == _oldParam.Type)
                {
                    var typeMap = _configurationProvider.ResolveTypeMap(sourceType: _newParam.Type, destinationType: node.Type);

                    IEnumerable<MemberBinding> bindings = node.Bindings.Aggregate(new List<MemberBinding>(), (list, binding) =>
                    {
                        var propertyMap = typeMap.PropertyMaps.SingleOrDefault(item => item.DestinationName == binding.Member.Name);
                        if (propertyMap == null)
                            return list;

                        var sourceMember = GetSourceMember(propertyMap);
                        if (sourceMember == null)
                            return list;

                        Expression bindingExpression = ((MemberAssignment)binding).Expression;
                        list.Add
                        (
                            DoBind
                            (
                                sourceMember,
                                bindingExpression,
                                this.Visit(bindingExpression)
                            )
                        );

                        return list;
                    });

                    return Expression.MemberInit(Expression.New(_newParam.Type), bindings);
                }

                return base.VisitMemberInit(node);
            }

            private MemberBinding DoBind(MemberInfo sourceMember, Expression initial, Expression mapped)
            {
                mapped = mapped.ConvertTypeIfNecessary(sourceMember.GetMemberType());
                return Expression.Bind(sourceMember, mapped);
            }

            private MemberInfo GetSourceMember(PropertyMap propertyMap)
                => propertyMap.CustomMapExpression != null
                    ? propertyMap.CustomMapExpression.GetMemberExpression()?.Member
                    : propertyMap.SourceMember;

This sample works for your test case if I remove the lines you added. It only covers the top level types though. From looking at the code in this class it recursively creates new visitors to handle child property maps.

If you're interested then maybe it's best to close this one and try the other approach.

@4E-69-63-6B-20-42-6F-73
Copy link
Author

Okay. I see why the other approach is better, so I will close this one and try again

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants