private void UpdateChildMemberDataSources(ObjectMapperData toTargetMapperData) { var targetMemberDataSources = MapperData.DataSourcesByTargetMember; var targetMembers = targetMemberDataSources.Keys.ToArray(); var dataSources = targetMemberDataSources.Values.ToArray(); var toTargetTargetMemberDataSources = toTargetMapperData.DataSourcesByTargetMember; var targetMembersCount = targetMembers.Length; var targetMemberIndex = 0; foreach (var toTargetMemberAndDataSource in toTargetTargetMemberDataSources) { var toTargetMember = toTargetMemberAndDataSource.Key.LeafMember; for (var i = targetMemberIndex; i < targetMembersCount; ++i) { ++targetMemberIndex; var targetMember = targetMembers[i]; if (!targetMember.LeafMember.Equals(toTargetMember)) { continue; } if (!dataSources[i].HasValue) { targetMemberDataSources[targetMember] = toTargetMemberAndDataSource.Value; } break; } } }
private Expression GetMappingBlock(IList <Expression> mappingExpressions, ObjectMapperData mapperData) { if (mappingExpressions[0].NodeType != ExpressionType.Block) { var objectAssignment = mappingExpressions.First(exp => exp.NodeType == ExpressionType.Assign); if (mappingExpressions.Last() == objectAssignment) { var assignment = (BinaryExpression)objectAssignment; var assignedValue = assignment.Right; if (assignedValue.NodeType == ExpressionType.Invoke) { assignedValue = assignedValue.Replace(mapperData.InstanceVariable, mapperData.TargetObject); } if (mappingExpressions.Count == 1) { return(Expression.Block(assignedValue)); } mappingExpressions[mappingExpressions.Count - 1] = assignedValue; return(Expression.Block(mappingExpressions)); } } mappingExpressions.Add(Expression.Label(mapperData.ReturnLabelTarget, GetReturnValue(mapperData))); var mappingBlock = Expression.Block(new[] { mapperData.InstanceVariable }, mappingExpressions); return(mappingBlock); }
private static Expression GetChildMapping( IObjectMappingData childMappingData, MappingValues mappingValues, int dataSourceIndex, ObjectMapperData declaredTypeMapperData) { var childMapperData = childMappingData.MapperData; if (childMapperData.TargetMemberEverRecurses()) { var mapRecursionCall = GetMapRecursionCallFor( childMappingData, mappingValues.SourceValue, dataSourceIndex, declaredTypeMapperData); return(mapRecursionCall); } var inlineMappingBlock = GetInlineMappingBlock( childMappingData, MappingDataFactory.ForChildMethod, mappingValues, new[] { mappingValues.SourceValue, mappingValues.TargetValue, mappingValues.EnumerableIndex, Expression.Constant(childMapperData.TargetMember.RegistrationName), Expression.Constant(dataSourceIndex), declaredTypeMapperData.GetParentMappingDataObjectAccess() }); return(inlineMappingBlock); }
private static IEnumerable <DictionaryTargetMember> EnumerateTargetMembers( IEnumerable <Member> sourceMembers, DictionaryTargetMember targetDictionaryMember, ObjectMapperData mapperData, Func <Member, string> targetMemberNameFactory) { foreach (var sourceMember in sourceMembers) { var targetEntryMemberName = targetMemberNameFactory.Invoke(sourceMember); var targetEntryMember = targetDictionaryMember.Append(sourceMember.DeclaringType, targetEntryMemberName); if (targetDictionaryMember.HasObjectEntries) { targetEntryMember = (DictionaryTargetMember)targetEntryMember.WithType(sourceMember.Type); } var entryMapperData = new ChildMemberMapperData(targetEntryMember, mapperData); var configuredKey = GetCustomKeyOrNull(entryMapperData); if (configuredKey != null) { targetEntryMember.SetCustomKey(configuredKey); } if (!sourceMember.IsSimple && !targetDictionaryMember.HasComplexEntries) { targetEntryMember = targetEntryMember.WithTypeOf(sourceMember); } yield return(targetEntryMember); } }
public static Expression GetChildMapping( IObjectMappingData childMappingData, MappingValues mappingValues, int dataSourceIndex, ObjectMapperData declaredTypeMapperData) { var childMapperData = childMappingData.MapperData; if (childMapperData.IsRepeatMapping && childMapperData.RuleSet.RepeatMappingStrategy.AppliesTo(childMapperData)) { var repeatMappingCall = childMapperData .RuleSet .RepeatMappingStrategy .GetMapRepeatedCallFor( childMappingData, mappingValues, dataSourceIndex, declaredTypeMapperData); return(repeatMappingCall); } var inlineMappingBlock = GetInlineMappingBlock( childMappingData, mappingValues, MappingDataCreationFactory.ForChild(mappingValues, dataSourceIndex, childMapperData)); return(inlineMappingBlock); }
public static Expression UseLocalSourceValueVariableIfAppropriate( Expression mappingExpression, ObjectMapperData mapperData) { if (mapperData.Context.IsForDerivedType || !mapperData.Context.IsStandalone || mapperData.UseSingleMappingExpression()) { return(mappingExpression); } if (!ShouldUseLocalSourceValueVariable(mapperData.SourceObject, mappingExpression, mapperData)) { return(mappingExpression); } var sourceValueVariableName = GetSourceValueVariableName(mapperData); var sourceValueVariable = Expression.Variable(mapperData.SourceType, sourceValueVariableName); return(UseLocalValueVariable( sourceValueVariable, mapperData.SourceObject, mappingExpression, performValueReplacement: true)); }
private ParameterExpression GetMappingDataObject(ObjectMapperData parent) { var mdType = typeof(IObjectMappingData <,>).MakeGenericType(SourceType, TargetType); var variableNameIndex = default(int?); while (parent != null) { if (parent.MappingDataObject.Type == mdType) { variableNameIndex = variableNameIndex.HasValue ? (variableNameIndex + 1) : 2; } parent = parent.Parent; } var mappingDataVariableName = string.Format( CultureInfo.InvariantCulture, "{0}To{1}Data{2}", SourceType.GetShortVariableName(), TargetType.GetShortVariableName().ToPascalCase(), variableNameIndex); var parameter = Expression.Parameter(mdType, mappingDataVariableName); return(parameter); }
private static IEnumerable <DictionaryTargetMember> GetParentContextFlattenedTargetMembers( ObjectMapperData mapperData, DictionaryTargetMember targetDictionaryMember) { while (mapperData.Parent != null) { mapperData = mapperData.Parent; var sourceMembers = GlobalContext.Instance .MemberCache .GetSourceMembers(mapperData.SourceType) .SelectMany(sm => MatchingFlattenedMembers(sm, targetDictionaryMember)) .ToArray(); var targetMembers = EnumerateTargetMembers( sourceMembers, targetDictionaryMember, mapperData, m => m.Name.StartsWithIgnoreCase(targetDictionaryMember.Name) ? m.Name.Substring(targetDictionaryMember.Name.Length) : m.Name); foreach (var targetMember in targetMembers) { yield return(targetMember); } } }
public static Expression ForChild( MappingValues mappingValues, int dataSourceIndex, ObjectMapperData childMapperData) { if (UseAsConversion(childMapperData, out var asConversion)) { return(asConversion); } var createMethod = MappingDataFactory .ForChildMethod .MakeGenericMethod(childMapperData.SourceType, childMapperData.TargetType); var createCall = Expression.Call( createMethod, mappingValues.SourceValue, mappingValues.TargetValue, mappingValues.EnumerableIndex, childMapperData.TargetMember.RegistrationName.ToConstantExpression(), dataSourceIndex.ToConstantExpression(), childMapperData.Parent.MappingDataObject); return(createCall); }
private static IEnumerable <QualifiedMember> EnumerateAllTargetMembers(ObjectMapperData mapperData) { var sourceMembers = GlobalContext.Instance.MemberCache.GetSourceMembers(mapperData.SourceType); var targetDictionaryMember = (DictionaryTargetMember)mapperData.TargetMember; var targetMembers = EnumerateTargetMembers( sourceMembers, targetDictionaryMember, mapperData, m => m.Name); foreach (var targetMember in targetMembers) { yield return(targetMember); } if (mapperData.IsRoot) { yield break; } foreach (var targetMember in GetParentContextFlattenedTargetMembers(mapperData, targetDictionaryMember)) { yield return(targetMember); } }
public static Expression ForElement( MappingValues mappingValues, ObjectMapperData elementMapperData) { if (UseAsConversion(elementMapperData, out var asConversion)) { return(asConversion); } var createMethod = MappingDataFactory .ForElementMethod .MakeGenericMethod(mappingValues.SourceValue.Type, mappingValues.TargetValue.Type); var enumerableMappingDataObject = elementMapperData.Context.IsStandalone ? typeof(IObjectMappingData).ToDefaultExpression() : (Expression)elementMapperData.Parent.MappingDataObject; var createCall = Expression.Call( createMethod, mappingValues.SourceValue, mappingValues.TargetValue, mappingValues.ElementIndex, mappingValues.ElementKey.GetConversionToObject(), enumerableMappingDataObject); return(createCall); }
private static bool UseExistingMapperData <TSource, TTarget>( ObjectMappingData <TSource, TTarget> mappingData, out ObjectMapperData existingMapperData) { if (!mappingData.IsPartOfRepeatedMapping) { existingMapperData = null; return(false); } // RepeatedMappings are invoked through the entry point MapperData, which assigns // itself as the ObjectMappingData's parent. If a repeated mapping then needs to // do a runtime-typed child mapping, we're able to reuse the parent MapperData // by finding it from the entry point: var parentMapperData = mappingData.Parent.MapperData; var membersSource = mappingData.MapperKey.GetMembersSource(parentMapperData); if (!(membersSource is IChildMembersSource childMembersSource)) { existingMapperData = null; return(false); } var mapperTypes = new[] { typeof(TSource), typeof(TTarget) }; existingMapperData = GetMapperDataOrNull( parentMapperData, mapperTypes, childMembersSource.TargetMemberRegistrationName); return(existingMapperData != null); }
public ObjectMapper( Expression <MapperFunc <TSource, TTarget> > mappingLambda, ObjectMapperData mapperData) { MappingLambda = mappingLambda; MapperData = mapperData; if (mapperData.Context.Compile) { _mapperFunc = mappingLambda.Compile(); } if (mapperData.Context.NeedsChildMapping) { _childMappersByKey = mapperData.MapperContext.Cache.CreateNew <ObjectMapperKeyBase, IObjectMapper>(); } else if (mapperData.Context.NeedsElementMapping) { _elementMappersByKey = mapperData.MapperContext.Cache.CreateNew <ObjectMapperKeyBase, IObjectMapper>(); } if (mapperData.HasMapperFuncs) { _recursionMappingFuncsByKey = CreateRecursionMapperFuncs(); } }
public static bool UseLocalSourceValueVariable( Expression sourceValue, Expression mapping, ObjectMapperData mapperData) { return((sourceValue.NodeType != ExpressionType.Parameter) && SourceAccessFinder.MultipleAccessesExist(mapperData, mapping)); }
public MapperDataContext( ObjectMapperData mapperData, bool isStandalone, bool isForDerivedType) { _mapperData = mapperData; IsStandalone = isStandalone; IsForDerivedType = isForDerivedType; }
private MapperDataContext( ObjectMapperData mapperData, bool isStandalone, bool isForDerivedType, IBasicMapperData basicMapperData) { _mapperData = mapperData; IsStandalone = isStandalone; IsForDerivedType = isForDerivedType; UseLocalVariable = isForDerivedType || ShouldUseLocalVariable(basicMapperData); }
private static QualifiedMember GetTargetMember( string targetMemberRegistrationName, ObjectMapperData mapperData) { var targetMember = mapperData .DataSourcesByTargetMember .Keys .FirstOrDefault(k => k.RegistrationName == targetMemberRegistrationName); return(targetMember); }
private MapperDataContext( ObjectMapperData mapperData, bool isStandalone, bool isForDerivedType, IQualifiedMemberContext context) { _mapperData = mapperData; IsStandalone = isStandalone; IsForDerivedType = isForDerivedType; UseLocalVariable = isForDerivedType || ShouldUseLocalVariable(context); }
private static void UpdateEnumerableVariablesIfAppropriate( ObjectMapperData fromMapperData, ObjectMapperData toMapperData) { if (fromMapperData.EnumerablePopulationBuilder.TargetVariable == null) { return; } toMapperData.LocalVariable = fromMapperData.LocalVariable; toMapperData.EnumerablePopulationBuilder.TargetVariable = fromMapperData.EnumerablePopulationBuilder.TargetVariable; }
private static bool UseAsConversion(ObjectMapperData childMapperData, out Expression conversion) { if (childMapperData.Context.IsStandalone) { conversion = childMapperData .DeclaredTypeMapperData .GetAsCall(childMapperData.SourceType, childMapperData.TargetType); return(true); } conversion = null; return(false); }
public EnumerablePopulationBuilder(ObjectMapperData omd) { _omd = omd; _sourceItemsSelector = new SourceItemsSelector(this); _sourceElementType = omd.SourceType.GetEnumerableElementType(); _targetTypeHelper = new EnumerableTypeHelper(omd.TargetType, omd.TargetMember.ElementType); _targetElementType = _targetTypeHelper.ElementType; ElementTypesAreTheSame = _sourceElementType == _targetElementType; ElementTypesAreSimple = _targetElementType.IsSimple(); _sourceElementParameter = _sourceElementType.GetOrCreateParameter(); _populationExpressions = new List <Expression>(); }
private static Expression GetCreateMappingDataCall( MethodInfo createMethod, ObjectMapperData childMapperData, Expression[] createMethodCallArguments) { if (childMapperData.Context.IsStandalone) { return(childMapperData.DeclaredTypeMapperData .GetAsCall(childMapperData.SourceType, childMapperData.TargetType)); } return(Expression.Call( createMethod.MakeGenericMethod(childMapperData.SourceType, childMapperData.TargetType), createMethodCallArguments)); }
private SimpleMemberMapperData( IQualifiedMember sourceMember, QualifiedMember targetMember, ObjectMapperData enumerableMapperData) : base( enumerableMapperData.RuleSet, sourceMember, targetMember, enumerableMapperData, enumerableMapperData.MapperContext) { ParentObject = GetParentObjectAccess(); ElementIndex = GetElementIndexAccess(); ElementKey = GetElementKeyAccess(); ElementIndexValue = enumerableMapperData.EnumerablePopulationBuilder.Counter.GetConversionTo <int?>(); }
public static Expression UseLocalToTargetDataSourceVariableIfAppropriate( ObjectMapperData mapperData, ObjectMapperData toTargetMapperData, Expression toTargetDataSourceValue, Expression mappingExpression) { if (!toTargetMapperData.Context.UsesMappingDataObject) { return(mappingExpression); } return(UseLocalValueVariable( toTargetMapperData.MappingDataObject, MappingDataCreationFactory.ForToTarget(mapperData, toTargetDataSourceValue), mappingExpression)); }
public static Expression ForToTarget( ObjectMapperData parentMapperData, Expression toTargetDataSource) { var withSourceMethod = parentMapperData .MappingDataObject .Type .GetPublicInstanceMethod("WithSource") .MakeGenericMethod(toTargetDataSource.Type); var withSourceCall = Expression.Call( parentMapperData.MappingDataObject, withSourceMethod, toTargetDataSource); return(withSourceCall); }
private static IDataSource GetMappingFactoryDataSource( ObjectMapperData mapperData, ConfiguredObjectFactory factory) { var condition = factory.GetConditionOrNull(mapperData); var value = factory.Create(mapperData); var returnLabelMapperData = mapperData.OriginalMapperData ?? mapperData; var returnValue = returnLabelMapperData.GetReturnExpression(value); return(new ConfiguredDataSource( mapperData.SourceMember, condition, returnValue, factory.ConfigInfo.IsSequentialConfiguration, factory.ConfigInfo.HasTargetMemberMatcher(), mapperData)); }
private static Expression GetMapRecursionCallFor( IObjectMappingData childMappingData, Expression sourceValue, int dataSourceIndex, ObjectMapperData declaredTypeMapperData) { var childMapperData = childMappingData.MapperData; childMapperData.RegisterRequiredMapperFunc(childMappingData); var mapRecursionCall = declaredTypeMapperData.GetMapRecursionCall( sourceValue, childMapperData.TargetMember, dataSourceIndex); return(mapRecursionCall); }
private static bool CreateElementMappingDataFor( ObjectMapperData mapperData, Expression sourceElementValue) { if (!mapperData.TargetMemberIsEnumerableElement()) { return(true); } if (mapperData.TargetMember.IsEnumerable) { return(!mapperData.EnumerablePopulationBuilder.TargetElementsAreSimple && sourceElementValue.Type.IsAssignableTo(mapperData.SourceMember.ElementType)); } return(false); }
private static Expression GetObjectRegistrationCallOrNull(ObjectMapperData mapperData) { if (mapperData.TargetTypeWillNotBeMappedAgain) { return(null); } if (mapperData.MapperContext.UserConfigurations.DisableObjectTracking(mapperData)) { return(null); } return(Expression.Call( mapperData.EntryPointMapperData.MappingDataObject, _registerMethod.MakeGenericMethod(mapperData.SourceType, mapperData.TargetType), mapperData.SourceObject, mapperData.InstanceVariable)); }
private bool IsTargetTypeFirstMapping(ObjectMapperData parent) { if (IsRoot) { return(true); } while (parent != null) { if (parent.HasTypeBeenMapped(TargetType, this)) { return(false); } parent = parent.Parent; } return(true); }