private static Expression NewExpr(this Type baseType, Type ifInterfaceType) { var newExpr = baseType.IsInterface() ? Expression.New( ifInterfaceType.MakeGenericType(ElementTypeHelper.GetElementTypes(baseType, ElementTypeFlags.BreakKeyValuePair))) : DelegateFactory.GenerateConstructorExpression(baseType); return(newExpr); }
public static Expression MapItemExpr(IConfigurationProvider configurationProvider, ProfileMap profileMap, Type sourceType, Type destType, Expression contextParam, out ParameterExpression itemParam) { var sourceElementType = ElementTypeHelper.GetElementType(sourceType); var destElementType = ElementTypeHelper.GetElementType(destType); itemParam = Expression.Parameter(sourceElementType, "item"); var typePair = new TypePair(sourceElementType, destElementType); var itemExpr = ExpressionBuilder.MapExpression(configurationProvider, profileMap, typePair, itemParam, contextParam); return(ExpressionFactory.ToType(itemExpr, destElementType)); }
public static Expression MapKeyPairValueExpr(IConfigurationProvider configurationProvider, ProfileMap profileMap, Type sourceType, Type destType, Expression contextParam, out ParameterExpression itemParam) { var sourceElementTypes = ElementTypeHelper.GetElementTypes(sourceType, ElementTypeFlags.BreakKeyValuePair); var destElementTypes = ElementTypeHelper.GetElementTypes(destType, ElementTypeFlags.BreakKeyValuePair); var typePairKey = new TypePair(sourceElementTypes[0], destElementTypes[0]); var typePairValue = new TypePair(sourceElementTypes[1], destElementTypes[1]); var sourceElementType = typeof(KeyValuePair <,>).MakeGenericType(sourceElementTypes); itemParam = Expression.Parameter(sourceElementType, "item"); var destElementType = typeof(KeyValuePair <,>).MakeGenericType(destElementTypes); var keyExpr = ExpressionBuilder.MapExpression(configurationProvider, profileMap, typePairKey, Expression.Property(itemParam, "Key"), contextParam); var valueExpr = ExpressionBuilder.MapExpression(configurationProvider, profileMap, typePairValue, Expression.Property(itemParam, "Value"), contextParam); var keyPair = Expression.New(destElementType.GetDeclaredConstructors().First(), keyExpr, valueExpr); return(keyPair); }
public static Expression MapCollectionExpression(IConfigurationProvider configurationProvider, ProfileMap profileMap, IMemberMap memberMap, Expression sourceExpression, Expression destExpression, Expression contextExpression, Type ifInterfaceType, MapItem mapItem) { var passedDestination = Expression.Variable(destExpression.Type, "passedDestination"); var newExpression = Expression.Variable(passedDestination.Type, "collectionDestination"); var sourceElementType = ElementTypeHelper.GetElementType(sourceExpression.Type); var itemExpr = mapItem(configurationProvider, profileMap, sourceExpression.Type, passedDestination.Type, contextExpression, out ParameterExpression itemParam); var destinationElementType = itemExpr.Type; var destinationCollectionType = typeof(ICollection <>).MakeGenericType(destinationElementType); if (!destinationCollectionType.IsAssignableFrom(destExpression.Type)) { destinationCollectionType = typeof(IList); } var addMethod = destinationCollectionType.GetDeclaredMethod("Add"); Expression destination, assignNewExpression; UseDestinationValue(); var addItems = ExpressionFactory.ForEach(sourceExpression, itemParam, Expression.Call(destination, addMethod, itemExpr)); var mapExpr = Expression.Block(addItems, destination); var clearMethod = destinationCollectionType.GetDeclaredMethod("Clear"); var checkNull = Expression.Block(new[] { newExpression, passedDestination }, Expression.Assign(passedDestination, destExpression), assignNewExpression, Expression.Call(destination, clearMethod), mapExpr ); if (memberMap != null) { return(checkNull); } var elementTypeMap = configurationProvider.ResolveTypeMap(sourceElementType, destinationElementType); if (elementTypeMap == null) { return(checkNull); } var checkContext = ExpressionBuilder.CheckContext(elementTypeMap, contextExpression); if (checkContext == null) { return(checkNull); } return(Expression.Block(checkContext, checkNull)); void UseDestinationValue() { if (memberMap?.UseDestinationValue == true) { destination = passedDestination; assignNewExpression = Expression.Empty(); } else { destination = newExpression; Expression createInstance = passedDestination.Type.NewExpr(ifInterfaceType); var isReadOnly = Expression.Property(ExpressionFactory.ToType(passedDestination, destinationCollectionType), "IsReadOnly"); assignNewExpression = Expression.Assign(newExpression, Expression.Condition(Expression.OrElse(Expression.Equal(passedDestination, Expression.Constant(null)), isReadOnly), ExpressionFactory.ToType(createInstance, passedDestination.Type), passedDestination)); } } }