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)); }
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) ) )); }
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)); }
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)); }
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) ) )); }