private static Expression GetConversionOrCreationExpression( this IMemberMapperData mapperData, Expression value, Type targetType, IList <ConfiguredObjectFactory> valueFactories) { var simpleMemberMapperData = SimpleMemberMapperData.Create(value, mapperData); var checkNestedAccesses = simpleMemberMapperData.TargetMemberIsEnumerableElement() && value.Type.CanBeNull(); var replacements = FixedSizeExpressionReplacementDictionary .WithEquivalentKeys(3) .Add(simpleMemberMapperData.SourceObject, value) .Add(simpleMemberMapperData.TargetObject, mapperData.GetTargetMemberAccess()) .Add(simpleMemberMapperData.ElementIndex, simpleMemberMapperData.ElementIndexValue); var conversions = valueFactories.ProjectToArray(vf => { var factoryExpression = vf.Create(simpleMemberMapperData); var condition = vf.GetConditionOrNull(simpleMemberMapperData); if (checkNestedAccesses) { var nestedAccessChecks = NestedAccessChecksFactory .GetNestedAccessChecksFor(factoryExpression); if (nestedAccessChecks != null) { condition = condition != null ? Expression.AndAlso(nestedAccessChecks, condition) : nestedAccessChecks; } } return(new SimpleTypeValueFactory { Factory = factoryExpression.Replace(replacements).GetConversionTo(targetType), Condition = condition?.Replace(replacements) }); }); if (conversions.Last().Condition != null) { conversions = conversions.Append(new SimpleTypeValueFactory { Factory = mapperData.GetValueConversion(value, targetType) ?? simpleMemberMapperData.GetTargetMemberDefault() }); } else if (conversions.Length == 1) { return(conversions[0].Factory); } return(GetConversionExpression(conversions)); }
public Expression Inject(Type[] contextTypes, IMemberMapperData mapperData) { if (mapperData.MappingDataObject.Type.IsAssignableTo(_contextType)) { return(_lambda.ReplaceParameterWith(mapperData.MappingDataObject)); } var args = new ValueInjectionArgs(_lambda, _configInfo, contextTypes, mapperData); var context = args.GetAppropriateMappingContext(); if (_isMappingContextInvokeLambda) { return(args.GetInvocationContextArgument(context)); } var targetContextTypes = _contextType.GetGenericTypeArguments(); var contextType = context.IsCallback(targetContextTypes) ? _contextType : _contextType.GetAllInterfaces().First(); var requiredValues = GetRequiredValues(); var replacements = FixedSizeExpressionReplacementDictionary .WithEquivalentKeys(requiredValues.ValuesCount); if (requiredValues.Includes(Parent)) { replacements.Add(PropertyAccess(nameof(Parent), contextType), context.GetParentAccess()); } if (requiredValues.Includes(Source)) { replacements.Add(PropertyAccess(RootSourceMemberName, contextType), context.GetSourceAccess()); } if (requiredValues.Includes(Target)) { replacements.Add(PropertyAccess(RootTargetMemberName, contextType), context.GetTargetAccess()); } if (requiredValues.Includes(CreatedObject)) { replacements.Add(PropertyAccess(nameof(CreatedObject), contextType), context.GetCreatedObject()); } if (requiredValues.Includes(ElementIndex)) { replacements.Add(PropertyAccess(nameof(ElementIndex), contextType), context.GetElementIndex()); } if (requiredValues.Includes(ElementKey)) { replacements.Add(PropertyAccess(nameof(ElementKey), contextType), context.GetElementKey()); } return(_lambda.Body.Replace(replacements)); }
protected override Expression GetFilterExpression(Expression sourceValue, ref bool hasFixedValueOperands) { var conditionReplacements = FixedSizeExpressionReplacementDictionary.WithEqualKeys(_filterConditions.Count); foreach (var filterCondition in _filterConditions) { conditionReplacements.Add( filterCondition.Filter, filterCondition.GetConditionReplacement(sourceValue, ref hasFixedValueOperands)); } return(ValuesFilter.Replace(conditionReplacements)); }
public static Expression GetDirectAccessMapping( Expression mapping, IMemberMapperData mapperData, MappingValues mappingValues, Expression createMappingDataCall) { var useLocalSourceValueVariable = ShouldUseLocalSourceValueVariable(mappingValues.SourceValue, mapping, mapperData); Expression sourceValue, sourceValueVariableValue; if (useLocalSourceValueVariable) { var sourceValueVariableName = mappingValues.SourceValue.Type.GetSourceValueVariableName(); sourceValue = Expression.Variable(mappingValues.SourceValue.Type, sourceValueVariableName); sourceValueVariableValue = mappingValues.SourceValue; } else { sourceValue = mappingValues.SourceValue; sourceValueVariableValue = null; } var replacementsByTarget = FixedSizeExpressionReplacementDictionary .WithEquivalentKeys(4) .Add(mapperData.SourceObject, sourceValue) .Add(mapperData.TargetObject, mappingValues.TargetValue) .Add(mapperData.ElementKey, mappingValues.ElementKey) .Add( mapperData.ElementIndex, mappingValues.ElementIndex.GetConversionTo(mapperData.ElementIndex.Type)); mapping = mapping .Replace(replacementsByTarget) .Replace(mapperData.MappingDataObject, createMappingDataCall); return(useLocalSourceValueVariable ? UseLocalValueVariable( (ParameterExpression)sourceValue, sourceValueVariableValue, mapping, mapperData) : mapping); }
public override Expression Inject(Type[] contextTypes, IMemberMapperData mapperData) { var replacements = _isInvocation ? FixedSizeExpressionReplacementDictionary.WithEqualKeys(RequiredValuesCount) : FixedSizeExpressionReplacementDictionary.WithEquivalentKeys(RequiredValuesCount); var context = CreateContext(contextTypes, mapperData); if (_requiredValues.Includes(MappingContext)) { replacements.Add(_requiredValues.MappingContext, context.GetMappingDataAccess()); } if (_requiredValues.Includes(Source)) { replacements.Add(_requiredValues.Source, context.GetSourceAccess()); } if (_requiredValues.Includes(Target)) { replacements.Add(_requiredValues.Target, context.GetTargetAccess()); } if (_requiredValues.Includes(CreatedObject)) { replacements.Add(_requiredValues.CreatedObject, context.GetCreatedObject()); } if (_requiredValues.Includes(ElementIndex)) { replacements.Add(_requiredValues.ElementIndex, context.GetElementIndex()); } if (_requiredValues.Includes(ElementKey)) { replacements.Add(_requiredValues.ElementKey, context.GetElementKey()); } return(_lambdaBody.Replace(replacements)); }
protected override Expression GetTargetObjectCreation( IObjectMappingData mappingData, IList <Expression> memberPopulations) { var objectCreation = base.GetTargetObjectCreation(mappingData, memberPopulations); if (objectCreation == null) { memberPopulations.Clear(); return(null); } if (memberPopulations.None()) { return(objectCreation); } var memberBindings = GetMemberBindingsFrom(memberPopulations); if (memberBindings.None()) { return(objectCreation); } var objectNewings = NewExpressionFinder.FindIn(objectCreation); var newingReplacements = FixedSizeExpressionReplacementDictionary.WithEqualKeys(objectNewings.Count); foreach (var objectNewing in objectNewings) { var objectInit = Expression.MemberInit(objectNewing, memberBindings); newingReplacements.Add(objectNewing, objectInit); } var fullObjectInit = objectCreation.Replace(newingReplacements); return(fullObjectInit); }
private static Expression CacheMultiInvocationResults( IList <Expression> multiInvocations, IList <ParameterExpression> variables, Expression populationExpressions) { var multiInvocationsCount = multiInvocations.Count; var cachedValuesCount = multiInvocationsCount - 1; var valueVariablesByInvocation = FixedSizeExpressionReplacementDictionary .WithEquivalentKeys(cachedValuesCount); var previousValueVariableAssignment = default(Expression); var previousInvocation = default(Expression); var previousValueVariable = default(ParameterExpression); for (var i = 0; i < multiInvocationsCount; ++i) { var invocation = multiInvocations[i]; var valueVariable = variables[i]; var isLastInvocation = i == cachedValuesCount; var valueVariableValue = invocation; for (var j = 0; j < i; ++j) { valueVariableValue = valueVariableValue.Replace( valueVariablesByInvocation.Keys[j], valueVariablesByInvocation.Values[j], ExpressionEvaluation.Equivalator); } if (!isLastInvocation) { valueVariablesByInvocation.Add(valueVariableValue, valueVariable); } populationExpressions = populationExpressions.Replace( valueVariableValue, valueVariable, ExpressionEvaluation.Equivalator); Expression valueVariableAssignment; if ((previousInvocation != null) && invocation.IsRootedIn(previousInvocation)) { var chainedValueVariableInvocation = valueVariableValue .Replace(previousValueVariable, previousValueVariableAssignment); valueVariableAssignment = valueVariable.AssignTo(chainedValueVariableInvocation); var chainedAssignmentPopulation = populationExpressions.Replace( chainedValueVariableInvocation, valueVariableAssignment, ExpressionEvaluation.Equivalator, replacementCount: 1); if (chainedAssignmentPopulation != populationExpressions) { populationExpressions = chainedAssignmentPopulation; if (isLastInvocation) { return(populationExpressions); } goto SetPreviousValues; } } valueVariableAssignment = valueVariable.AssignTo(valueVariableValue); populationExpressions = populationExpressions.ReplaceParameter( valueVariable, valueVariableAssignment, replacementCount: 1); SetPreviousValues: previousInvocation = invocation; previousValueVariable = valueVariable; previousValueVariableAssignment = valueVariableAssignment; } return(populationExpressions); }