Esempio n. 1
0
        public virtual MemberBinding CreateMemberBinding(MapMember outMember, MapMember inMember, ParameterExpression inObjPrm, ParameterExpression mapContextPrm)
        {
            if (inMember.IsPrimitive)
            {
                Expression member = Expression.PropertyOrField(inObjPrm, inMember.Name);
                if (inMember.Type != outMember.Type)
                {
                    if (Helper.TypesCastable(inMember.Type, outMember.Type) || Nullable.GetUnderlyingType(inMember.Type) != null)
                    {
                        member = Expression.MakeUnary(ExpressionType.Convert, member, outMember.Type);
                    }
                    else
                    {
                        member = Expression.MakeUnary(ExpressionType.Convert, member, typeof(object));
                        member = Expression.Call(ChangeTypeMethod, member, Expression.Constant(outMember.Type));
                        member = Expression.MakeUnary(ExpressionType.Convert, member, outMember.Type);
                    }
                }

                return(Expression.Bind(outMember.MemberInfo, member));
            }

#if NET_STANDARD
            var inEnumerableType = inMember.Type.GetTypeInfo().ImplementedInterfaces
                                   .FirstOrDefault(i => i.GetTypeInfo().IsGenericType&& i.GetGenericTypeDefinition() == typeof(IEnumerable <>));
            var outEnumerableType = outMember.Type.GetTypeInfo().ImplementedInterfaces
                                    .FirstOrDefault(i => i.GetTypeInfo().IsGenericType&& i.GetGenericTypeDefinition() == typeof(IEnumerable <>));
#else
            var inEnumerableType = inMember.Type.GetInterfaces()
                                   .FirstOrDefault(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IEnumerable <>));
            var outEnumerableType = outMember.Type.GetInterfaces()
                                    .FirstOrDefault(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IEnumerable <>));
#endif

            if (inEnumerableType != null)
            {
                if (outEnumerableType == null)
                {
                    throw new ArrayTypeMismatchException($"Navigation type mismatch for property {outMember.Name}");
                }
            }
            else
            {
                if (outEnumerableType != null)
                {
                    throw new ArrayTypeMismatchException($"Navigation type mismatch for property {outMember.Name}");
                }

                return(Expression.Bind(
                           outMember.MemberInfo,
                           Expression.Call(
                               mapContextPrm,
                               MapMethod.MakeGenericMethod(inMember.Type, outMember.Type),
                               Expression.PropertyOrField(inObjPrm, inMember.Name)
                               )
                           ));
            }

            return(CreateEnumerableBinding(inMember, outMember, inEnumerableType, outEnumerableType, inObjPrm, mapContextPrm));
        }
Esempio n. 2
0
        protected virtual MemberBinding CreateEnumerableBinding(MapMember inMember, MapMember outMember, Type inEnumerableType, Type outEnumerableType,
                                                                ParameterExpression inObjPrm, ParameterExpression mapContextPrm)
        {
            MethodInfo mapMethod;

#if NET_STANDARD
            var outGenericType = outEnumerableType.GenericTypeArguments[0];
            var outList        = typeof(List <>).MakeGenericType(outGenericType);
            if (outMember.Type.GetTypeInfo().IsAssignableFrom(outList.GetTypeInfo()))
            {
                mapMethod = MapToListMethod.MakeGenericMethod(inEnumerableType.GenericTypeArguments[0], outGenericType);
            }
            else if (outMember.Type.IsArray)
            {
                mapMethod = MapToArrayMethod.MakeGenericMethod(inEnumerableType.GenericTypeArguments[0], outGenericType);
            }
            else if (outGenericType.GetTypeInfo().IsGenericType&& outGenericType.GetGenericTypeDefinition() == typeof(KeyValuePair <,>))
            {
                var inGens  = inMember.Type.GenericTypeArguments;
                var outGens = outMember.Type.GenericTypeArguments;
                mapMethod = MapToDictionaryMethod.MakeGenericMethod(inGens[0], inGens[1], outGens[0], outGens[1]);
            }
            else
            {
                mapMethod = MapToCollectionTypeMethod.MakeGenericMethod(inEnumerableType.GenericTypeArguments[0], outGenericType, outMember.Type);
            }
#else
            var outGenericType = outEnumerableType.GetGenericArguments()[0];
            var outList        = typeof(List <>).MakeGenericType(outGenericType);
            if (outMember.Type.IsAssignableFrom(outList))
            {
                mapMethod = MapToListMethod.MakeGenericMethod(inEnumerableType.GetGenericArguments()[0], outGenericType);
            }
            else if (outMember.Type.IsArray)
            {
                mapMethod = MapToArrayMethod.MakeGenericMethod(inEnumerableType.GetGenericArguments()[0], outGenericType);
            }
            else if (outGenericType.IsGenericType && outGenericType.GetGenericTypeDefinition() == typeof(KeyValuePair <,>))
            {
                var inGens  = inMember.Type.GetGenericArguments();
                var outGens = outMember.Type.GetGenericArguments();
                mapMethod = MapToDictionaryMethod.MakeGenericMethod(inGens[0], inGens[1], outGens[0], outGens[1]);
            }
            else
            {
                mapMethod = MapToCollectionTypeMethod.MakeGenericMethod(inEnumerableType.GetGenericArguments()[0], outGenericType, outMember.Type);
            }
#endif

            return(Expression.Bind(
                       outMember.MemberInfo,
                       Expression.Call(
                           mapContextPrm,
                           mapMethod,
                           Expression.PropertyOrField(inObjPrm, inMember.Name)
                           )
                       ));
        }
Esempio n. 3
0
        private MemberBinding CreateMemberBinding(MapMember outMember, ParameterExpression inObjPrm, ParameterExpression mapContextPrm)
        {
            var inMember = _inMembers.FirstOrDefault(p => p.Name == outMember.Name);

            if (inMember == null)
            {
                return(null);
            }

            return(_expressionProvider.CreateMemberBinding(outMember, inMember, inObjPrm, mapContextPrm));
        }
Esempio n. 4
0
        protected virtual MemberBinding CreatePrimitiveEnumerableBinding(MapMember inMember, MapMember outMember,
                                                                         Type inGenericType, Type outGenericType,
                                                                         ParameterExpression inObjPrm)
        {
            Expression inMemberExp    = Expression.PropertyOrField(inObjPrm, inMember.Name);
            var        orgInMemberExp = inMemberExp;

            if (inGenericType != outGenericType)
            {
                var convertPrmExp = Expression.Parameter(inGenericType);
                var convertExp    = Expression.Lambda(
                    Expression.MakeUnary(ExpressionType.Convert, convertPrmExp, outGenericType),
                    convertPrmExp
                    );

                inMemberExp = Expression.Call(
                    null,
                    SelectMethod.MakeGenericMethod(inGenericType, outGenericType),
                    inMemberExp,
                    convertExp
                    );
            }

            MethodInfo copyMethod = null;
            var        outList    = typeof(List <>).MakeGenericType(outGenericType);

#if NET_STANDARD
            if (outMember.Type.GetTypeInfo().IsAssignableFrom(outList.GetTypeInfo()))
            {
                copyMethod = ToListMethod;
            }
            else if (outMember.Type.IsArray)
            {
                copyMethod = ToArrayMethod;
            }
#else
            if (outMember.Type.IsAssignableFrom(outList))
            {
                copyMethod = ToListMethod;
            }
            else if (outMember.Type.IsArray)
            {
                copyMethod = ToArrayMethod;
            }
#endif
            Expression copyExp;
            if (copyMethod != null)
            {
                copyMethod = copyMethod.MakeGenericMethod(outGenericType);
                copyExp    = Expression.Call(null, copyMethod, inMemberExp);
            }
            else
            {
#if NET_STANDARD
                var outCtor = outMember.Type.GetTypeInfo().DeclaredConstructors.FirstOrDefault(
                    c => {
                    var prms = c.GetParameters();
                    return(prms.Length == 1 && prms.First().ParameterType.GetTypeInfo().IsAssignableFrom(outList.GetTypeInfo()));
                }
                    );
#else
                var outCtor = outMember.Type.GetConstructors().FirstOrDefault(
                    c => {
                    var prms = c.GetParameters();
                    return(prms.Length == 1 && prms.First().ParameterType.IsAssignableFrom(outList));
                }
                    );
#endif
                if (outCtor == null)
                {
                    throw new NotSupportedException($"{outMember.Type} does not have a suitable constructor for mapping.");
                }

                copyExp = Expression.New(
                    outCtor,
                    Expression.Call(null, ToListMethod.MakeGenericMethod(outGenericType), inMemberExp)
                    );
            }

            var nullExp      = Expression.Constant(null, outMember.Type);
            var conditionExp = Expression.Condition(
                Expression.Equal(orgInMemberExp, Expression.Constant(null)),
                nullExp,
                copyExp
                );

            return(Expression.Bind(outMember.MemberInfo, conditionExp));
        }
Esempio n. 5
0
        public virtual MemberBinding CreateMemberBinding(MapMember outMember, MapMember inMember, ParameterExpression inObjPrm, ParameterExpression mapContextPrm)
        {
            if (inMember.IsPrimitive)
            {
                Expression member = Expression.PropertyOrField(inObjPrm, inMember.Name);
                if (inMember.Type != outMember.Type)
                {
                    member = Expression.MakeUnary(ExpressionType.Convert, member, outMember.Type);
                }

                return(Expression.Bind(outMember.MemberInfo, member));
            }

            var inMemberType  = inMember.Type;
            var outMemberType = outMember.Type;

            var inEnumerableType = inMember.Type.GetInterfaces()
                                   .FirstOrDefault(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IEnumerable <>));
            var outEnumerableType = outMember.Type.GetInterfaces()
                                    .FirstOrDefault(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IEnumerable <>));

            if (inEnumerableType != null)
            {
                if (outEnumerableType == null)
                {
                    throw new ArrayTypeMismatchException($"Navigation type mismatch for property {outMember.Name}");
                }
            }
            else
            {
                if (outEnumerableType != null)
                {
                    throw new ArrayTypeMismatchException($"Navigation type mismatch for property {outMember.Name}");
                }

                return(Expression.Bind(
                           outMember.MemberInfo,
                           Expression.Call(
                               mapContextPrm,
                               MapMethod.MakeGenericMethod(inMemberType, outMemberType),
                               Expression.PropertyOrField(inObjPrm, inMember.Name)
                               )
                           ));
            }

            var        outEnumType = outEnumerableType.GetGenericArguments()[0];
            MethodInfo mapMethod;

            if (outMember.Type.IsArray)
            {
                mapMethod = MapToArrayMethod.MakeGenericMethod(inEnumerableType.GetGenericArguments()[0], outEnumType);
            }
            else if (outEnumType.IsGenericType && outEnumType.GetGenericTypeDefinition() == typeof(KeyValuePair <,>))
            {
                var inGens  = inMemberType.GetGenericArguments();
                var outGens = outMember.Type.GetGenericArguments();
                mapMethod = MapToDictionaryMethod.MakeGenericMethod(inGens[0], inGens[1], outGens[0], outGens[1]);
            }
            else
            {
                mapMethod = MapToListMethod.MakeGenericMethod(inEnumerableType.GetGenericArguments()[0], outEnumType);
            }

            return(Expression.Bind(
                       outMember.MemberInfo,
                       Expression.Call(
                           mapContextPrm,
                           mapMethod,
                           Expression.PropertyOrField(inObjPrm, inMember.Name)
                           )
                       ));
        }