private TypeMap ResolveTypeMap(TypePair types) { var typeMap = _configurationProvider.ResolveTypeMap(types); if (typeMap == null && _configurationProvider.FindMapper(types) is IObjectMapperInfo mapper) { typeMap = _configurationProvider.ResolveTypeMap(mapper.GetAssociatedTypes(types)); } return(typeMap); }
private void DryRunTypeMap(ICollection <TypeMap> typeMapsChecked, TypePair types, TypeMap typeMap, IMemberMap memberMap) { if (typeMap == null) { if (types.SourceType.ContainsGenericParameters || types.DestinationType.ContainsGenericParameters) { return; } typeMap = _config.ResolveTypeMap(types.SourceType, types.DestinationType); } if (typeMap != null) { if (typeMap.IsClosedGeneric) { // it was already validated return; } if (typeMapsChecked.Contains(typeMap)) { return; } typeMapsChecked.Add(typeMap); var context = new ValidationContext(types, memberMap, typeMap); Validate(context); if (!typeMap.ShouldCheckForValid) { return; } CheckPropertyMaps(typeMapsChecked, typeMap); typeMap.IsValid = true; } else { var mapperToUse = _config.FindMapper(types); if (mapperToUse == null) { throw new AutoMapperConfigurationException(memberMap.TypeMap.Types) { MemberMap = memberMap }; } var context = new ValidationContext(types, memberMap, mapperToUse); Validate(context); if (mapperToUse is IObjectMapperInfo mapperInfo) { var newTypePair = mapperInfo.GetAssociatedTypes(types); DryRunTypeMap(typeMapsChecked, newTypePair, null, memberMap); } } }
private static Expression ObjectMapperExpression(IConfigurationProvider configurationProvider, ProfileMap profileMap, TypePair typePair, Expression sourceParameter, Expression contextParameter, PropertyMap propertyMap, Expression destinationParameter) { var match = configurationProvider.FindMapper(typePair); if (match != null) { var mapperExpression = match.MapExpression(configurationProvider, profileMap, propertyMap, sourceParameter, destinationParameter, contextParameter); return(mapperExpression); } return(ContextMap(typePair, sourceParameter, contextParameter, destinationParameter)); }
private TypeMap ResolvePropertyTypeMap(PropertyMap propertyMap) { if (propertyMap.SourceType == null) { return(null); } var types = new TypePair(propertyMap.SourceType, propertyMap.DestinationPropertyType); var typeMap = _configurationProvider.ResolveTypeMap(types); if (typeMap == null && _configurationProvider.FindMapper(types) is IObjectMapperInfo mapper) { typeMap = _configurationProvider.ResolveTypeMap(mapper.GetAssociatedTypes(types)); } return(typeMap); }
private void CheckForCycles(HashSet <TypeMap> typeMapsPath) { bool inlineWasChecked; if (_typeMap.ConstructorMappingTypes == null) { _typeMap.ConstructorMappingTypes = GetConstructorMappingTypes(); inlineWasChecked = false; } else { inlineWasChecked = true; } if (typeMapsPath == null) { typeMapsPath = new HashSet <TypeMap>(); } typeMapsPath.Add(_typeMap); var defaultPropertyMap = new PropertyMap(default(MemberInfo), null); var properties = _typeMap.GetPropertyMaps().Where(pm => pm.CanResolveValue()).Select(pm => new { PropertyTypeMap = ResolvePropertyTypeMap(pm), PropertyMap = pm }) .Concat(_typeMap.ConstructorMappingTypes.Select(tp => new { PropertyTypeMap = ResolveTypeMap(tp), PropertyMap = defaultPropertyMap })) .Where(p => p.PropertyTypeMap != null && !p.PropertyTypeMap.PreserveReferences && p.PropertyTypeMap.MapExpression == null); foreach (var property in properties) { if (!inlineWasChecked && typeMapsPath.Count % _configurationProvider.MaxExecutionPlanDepth == 0) { property.PropertyMap.Inline = false; Debug.WriteLine($"Resetting Inline: {property.PropertyMap.DestinationProperty} in {_typeMap.SourceType} - {_typeMap.DestinationType}"); } var propertyTypeMap = property.PropertyTypeMap; if (typeMapsPath.Contains(propertyTypeMap)) { if (propertyTypeMap.SourceType.IsValueType()) { if (propertyTypeMap.MaxDepth == 0) { propertyTypeMap.MaxDepth = 10; } typeMapsPath.Remove(_typeMap); return; } else { SetPreserveReferences(propertyTypeMap); foreach (var derivedTypeMap in propertyTypeMap.IncludedDerivedTypes.Select(typePair => ResolveTypeMap(typePair))) { SetPreserveReferences(derivedTypeMap); } } } propertyTypeMap.CheckForCycles(_configurationProvider, typeMapsPath); } typeMapsPath.Remove(_typeMap); return; void SetPreserveReferences(TypeMap propertyTypeMap) { Debug.WriteLine($"Setting PreserveReferences: {_typeMap.SourceType} - {_typeMap.DestinationType} => {propertyTypeMap.SourceType} - {propertyTypeMap.DestinationType}"); propertyTypeMap.PreserveReferences = true; } TypeMap ResolvePropertyTypeMap(PropertyMap propertyMap) { if (propertyMap.SourceType == null) { return(null); } var types = new TypePair(propertyMap.SourceType, propertyMap.DestinationPropertyType); return(ResolveTypeMap(types)); } TypeMap ResolveTypeMap(TypePair types) { var typeMap = _configurationProvider.ResolveTypeMap(types); if (typeMap == null && _configurationProvider.FindMapper(types) is IObjectMapperInfo mapper) { typeMap = _configurationProvider.ResolveTypeMap(mapper.GetAssociatedTypes(types)); } return(typeMap); } }