public ProposedMap CreateMapProposal(TypePair pair, MemberOptions options = null, LambdaExpression customMappingExpression = null, params Type[] parameters) { var map = new ProposedMap(pair.SourceType, pair.DestinationType, this.mapper, this.options); foreach (var param in parameters) { map.ParameterTypes.Add(param); } CustomMapping customMapping = null; customMapping = GetCustomMappingFromExpression(pair, customMappingExpression, customMapping); TryGetCustomMapping(pair, out customMapping); var mapping = GetComplexTypeMapping(0, pair, options ?? mapper.DefaultMemberOptions, customMapping, true); if (mapping.CustomMapping == null) { mapping.CustomMapping = customMapping; } map.ProposedTypeMapping = mapping; return(map); }
public void CreateCustomMap <TSource, TDestination>(Func <TSource, TDestination> func) where TDestination : new() { var key = GenerateKey <TSource, TDestination>(); var mapping = new CustomMapping <TSource, TDestination>(func); mappings.Add(key, mapping); }
public ProposedMap <TSource, TDestination, TParam> CreateMapProposal <TSource, TDestination, TParam>(MemberOptions options = null, Expression <Func <TSource, TParam, object> > customMappingExpression = null) { var map = new ProposedMap <TSource, TDestination, TParam>(this.mapper, this.options); map.ParameterTypes.Add(typeof(TParam)); var pair = new TypePair(typeof(TSource), typeof(TDestination)); CustomMapping customMapping = null; //if (customMappingExpression != null) //{ // customMapping = CustomMapping.GetCustomMapping(typeof(TDestination), customMappingExpression); // customMappingCache[pair] = customMapping; //} customMapping = GetCustomMappingFromExpression(pair, customMappingExpression, customMapping); TryGetCustomMapping(pair, out customMapping); var mapping = GetComplexTypeMapping(0, pair, options ?? mapper.DefaultMemberOptions, customMapping, true); if (mapping.CustomMapping == null) { mapping.CustomMapping = customMapping; } map.ProposedTypeMapping = mapping; return(map); }
private CustomMapping GetCustomMappingFromExpression(TypePair pair, LambdaExpression customMappingExpression, CustomMapping customMapping) { if (customMappingExpression != null) { customMapping = CustomMapping.GetCustomMapping(pair.DestinationType, customMappingExpression); customMappingCache[pair] = customMapping; } return(customMapping); }
public IQueryable <CustomerDto> GetTop1000Dtos() { try { var result = this.Get(null, c => c.OrderBy(ct => ct.Id), c => c.CustomerType).Take(1000); var output = CustomMapping.MapCustomerObjects(result); return(output); } catch (Exception e) { throw; } }
/// <summary> /// Gets the Top 1000 customers including their types navigation properties /// </summary> /// <returns></returns> // GET customers/GetTop1000 public JsonResult GetTop1000JSON() { //try //{ // //var result = CustomersBusinessManager // // .GetVM(null, c => c.OrderBy(ct => ct.Id), c => c.CustomerType).Take(1000); // //var resultSer = JsonConvert.SerializeObject(result, Formatting.Indented, // // new JsonSerializerSettings // // { // // ReferenceLoopHandling = ReferenceLoopHandling.Ignore // // }); // var result = CustomersBusinessManager.GetTop1000Dtos(); // return Json(result, JsonRequestBehavior.AllowGet); //} //catch (Exception e) //{ // throw; //} try { var result = CustomersBusinessManager .Get(null, c => c.OrderBy(ct => ct.Id), c => c.CustomerType).Take(1000); var output = CustomMapping.MapCustomerObjects(result); return(Json(output, JsonRequestBehavior.AllowGet)); } catch (Exception e) { throw; } }
private bool TryGetCustomMapping(TypePair pair, out CustomMapping customMapping) { if (CollectionTypeHelper.IsEnumerable(pair)) { var source = CollectionTypeHelper.GetTypeInsideEnumerable(pair.SourceType); var destination = CollectionTypeHelper.GetTypeInsideEnumerable(pair.DestinationType); pair = new TypePair(source, destination); } IEnumerable <CustomMapping> matchingMappings; customMappingCache.TryGetValue(pair, out customMapping); matchingMappings = (from m in customMappingCache where m.Key.DestinationType.IsAssignableFrom(pair.DestinationType) && m.Key.DestinationType != pair.DestinationType orderby DistanceFromType(pair.DestinationType, m.Key.DestinationType, 0) ascending select m.Value); matchingMappings = matchingMappings.Union(from m in customMappingCache where m.Key.SourceType.IsAssignableFrom(pair.SourceType) && m.Key.SourceType != pair.SourceType orderby DistanceFromType(pair.SourceType, m.Key.SourceType, 0) ascending select m.Value).ToList(); customMapping = customMapping ?? matchingMappings.FirstOrDefault(); if (customMapping != null) { customMapping.CombineWithOtherCustomMappings(matchingMappings); return(true); } else { return(false); } }
public void Define(string mapping, CustomMapping custom) { customMap.Add(mapping, custom); }
public static void Define(string mapping, int playerId, CustomMapping custom) { _player[playerId].Define(mapping, custom); }
public static void Define(string mapping, CustomMapping custom) { Define(mapping, 0, custom); }
private void BuildMemberAssignmentExpressions(Expression sourceAccess, List <MemberBinding> memberBindings, ProposedMemberMapping member, CustomMapping customMapping) { if (member.Ignored) { return; } Expression customExpression; MemberAssignment bindSourceToDest; if (customMapping != null && (customExpression = customMapping.GetExpressionForMember(member.DestinationMember)) != null) { processor.ParametersToReplace.Add(new ProjectionExpressionTuple(customMapping.SourceParameter, sourceAccess)); bindSourceToDest = Expression.Bind(member.DestinationMember, customExpression); } else { Expression accessMember = Expression.MakeMemberAccess(sourceAccess, member.SourceMember); accessMember = HandleNullableValueTypes(member, accessMember); bindSourceToDest = Expression.Bind(member.DestinationMember, accessMember); } memberBindings.Add(bindSourceToDest); }
private ProposedTypeMapping GetComplexTypeMapping(int currentDepth, TypePair complexPair, MemberOptions options, CustomMapping customMapping, bool skipCache = false) { if (complexPair.SourceType == complexPair.DestinationType) { var maxDepth = this.options.Cloning.MaxCloneDepth; if (maxDepth.HasValue && currentDepth > maxDepth) { return(null); } } else { var maxDepth = this.options.Conventions.MaxDepth; if (maxDepth.HasValue && currentDepth > maxDepth) { return(null); } } ProposedTypeMapping complexTypeMapping; if (skipCache || !mappingCache.TryGetValue(complexPair, out complexTypeMapping)) { ProposedMap proposedMap; if (mapper.MapRepository != null && mapper.MapRepository.TryGetMap(mapper, options, complexPair, out proposedMap)) { complexTypeMapping = proposedMap.ProposedTypeMapping; } else { complexTypeMapping = GetTypeMapping(currentDepth, complexPair, options, customMapping); } } return(complexTypeMapping); }
private void GenerateEnumerableMapping(int currentDepth, MemberOptions options, CustomMapping customMapping, ProposedTypeMapping typeMapping, PropertyOrFieldInfo destinationMember, PropertyOrFieldInfo sourceMember) { var typeOfSourceEnumerable = CollectionTypeHelper.GetTypeInsideEnumerable(sourceMember.PropertyOrFieldType); var typeOfDestinationEnumerable = CollectionTypeHelper.GetTypeInsideEnumerable(destinationMember.PropertyOrFieldType); var canAssignSourceItemsToDestination = CanAssignSourceItemsToDestination(destinationMember, sourceMember, typeOfSourceEnumerable, typeOfDestinationEnumerable); if (canAssignSourceItemsToDestination) { typeMapping.ProposedTypeMappings.Add( new ProposedTypeMapping { DestinationMember = destinationMember, SourceMember = sourceMember, ProposedMappings = new List <ProposedMemberMapping>() }); } else { var complexPair = new TypePair(typeOfSourceEnumerable, typeOfDestinationEnumerable); var complexTypeMapping = GetComplexTypeMapping(currentDepth + 1, complexPair, options, customMapping); if (complexTypeMapping != null) { complexTypeMapping = complexTypeMapping.Clone(); complexTypeMapping.DestinationMember = destinationMember; complexTypeMapping.SourceMember = sourceMember; CustomMapping customMappingForType; TryGetCustomMapping(complexPair, out customMappingForType); complexTypeMapping.CustomMapping = customMappingForType; typeMapping.ProposedTypeMappings.Add(complexTypeMapping); } else { typeMapping.DoNotCache = true; } } }
/// <summary> /// Go one deeper into the type hierarchy to map between a source and destination member. /// </summary> private void GenerateComplexTypeMapping(int currentDepth, MemberOptions options, CustomMapping customMapping, ProposedTypeMapping typeMapping, PropertyOrFieldInfo destinationMember, PropertyOrFieldInfo sourceMember) { var complexPair = new TypePair(sourceMember.PropertyOrFieldType, destinationMember.PropertyOrFieldType); // Go one deeper var complexTypeMapping = GetComplexTypeMapping(currentDepth + 1, complexPair, options, customMapping); // If a mapping has been found if (complexTypeMapping != null) { complexTypeMapping = complexTypeMapping.Clone(); complexTypeMapping.DestinationMember = destinationMember; complexTypeMapping.SourceMember = sourceMember; CustomMapping customMappingForType; TryGetCustomMapping(complexPair, out customMappingForType); complexTypeMapping.CustomMapping = customMappingForType; typeMapping.ProposedTypeMappings.Add(complexTypeMapping); } else { // If no mapping has been found, don't cache the 'owning' typemapping as it will cause issues later typeMapping.DoNotCache = true; } }
/// <summary> /// Returns a type mapping of the TypePair you pass in. /// </summary> /// <returns></returns> private ProposedTypeMapping GetTypeMapping(int currentDepth, TypePair pair, MemberOptions options = null, CustomMapping customMapping = null) { if (!typeStack.Contains(pair)) { typeStack.Push(pair); } else if (this.options.Safety.IfRecursiveRelationshipIsDetected == RecursivePropertyOptions.ThrowIfRecursionIsDetected) { // Oh noes, recursion! throw new RecursiveRelationshipException(pair); } // if it's a recursive relationship, by default we return null which is handled after the method returns else { return(null); } var typeMapping = new ProposedTypeMapping(); typeMapping.SourceMember = null; typeMapping.DestinationMember = null; Type destinationType, sourceType; // If it's an enumerable type (List<>, IEnumerable<>, etc) then we're currently interested // in the type 'inside' the enumerable. if (CollectionTypeHelper.IsEnumerable(pair.DestinationType)) { destinationType = CollectionTypeHelper.GetTypeInsideEnumerable(pair.DestinationType); } else { destinationType = pair.DestinationType; } // Same here. if (CollectionTypeHelper.IsEnumerable(pair.SourceType)) { sourceType = CollectionTypeHelper.GetTypeInsideEnumerable(pair.SourceType); } else { sourceType = pair.SourceType; } // The memberprovider is responsible for linking a destination member with a source member var memberProvider = this.strategy.MemberProviderFactory.GetMemberProvider(sourceType, destinationType, mapper); // Loop through all members it could find foreach (var mapping in GetTypeMembers(memberProvider, options, currentDepth)) { var destinationMember = mapping.Destination; var sourceMember = mapping.Source; // Does the memberprovider see any reason to ignore this member? if (memberProvider.IsMemberIgnored(sourceType, destinationMember)) { continue; } Expression customExpression = null; // Try to extract an expression that was supplied for this destination member if (customMapping != null) { customExpression = customMapping.GetExpressionForMember(destinationMember); if (mapping.ConversionFunction == null) { var conversionFunction = customMapping.GetConversionFunction(sourceMember, destinationMember); mapping.ConversionFunction = conversionFunction; } } // Did the user supply a function to transform the source member's value? if (mapping.ConversionFunction != null) { // If no custom mapping yet, then we need to create one // as it's where we'll be storing the conversion function if (customMapping == null) { customMapping = new CustomMapping { DestinationType = destinationType }; customMappingCache.AddOrUpdate(pair, customMapping, (k, v) => customMapping); typeMapping.CustomMapping = customMapping; } // Let the custom mapping be the owner of the conversion function customMapping.AddConversionFunction(sourceMember, destinationMember, mapping.ConversionFunction); } else if (customMapping != null) { } ProposedHierarchicalMapping hierarchicalMapping = null; // No source member or can't write to the destination? if (HasNoSourceMember(customExpression, sourceMember) || !destinationMember.CanWrite) { if (this.options.Conventions.AutomaticallyFlattenHierarchies) { // Propose a mapping that flattens a hierarchy if possible. // For example, map type.CompanyName to otherType.Company.Name hierarchicalMapping = memberProvider.ProposeHierarchicalMapping(destinationMember); } // No way to map this thing? Add it to incompatible members if the option has been turned on. // Will cause an (intended) exception later on, allowing you to verify your mappings // for correctness and completeness. if (hierarchicalMapping == null && this.options.Strictness.ThrowWithoutCorrespondingSourceMember) { typeMapping.IncompatibleMappings.Add(destinationMember); } } // Nullable value types screw up everything! var nullableType = NullableTypeHelper.TryGetNullableType(sourceMember); // Can we do a simple right to left assignment between the members? // So, are they basically the same type or do we need to do further mapping? var canUseSimpleTypeMapping = CanUseDirectAssignment(pair, destinationMember, sourceMember, nullableType, hierarchicalMapping); if (canUseSimpleTypeMapping) { // If simple mapping is possible create a mapping between the members typeMapping.ProposedMappings.Add ( new ProposedMemberMapping { SourceMember = sourceMember, DestinationMember = destinationMember, HierarchicalMapping = hierarchicalMapping } ); } // No simple assignment, but a custom expression is supplied // and that's just as good as having a direct assignment mapping else if (customExpression != null || mapping.ConversionFunction != null) { typeMapping.ProposedMappings.Add ( new ProposedMemberMapping { SourceMember = sourceMember, DestinationMember = destinationMember, HierarchicalMapping = hierarchicalMapping } ); } // We have a source member but can't directly assign the source to the destination. // Further mapping is needed. else if (sourceMember != null) { // Is the member of an IEnumerable type? if (AreMembersIEnumerable(destinationMember, sourceMember)) { // Create a deeper mapping for IEnumerable members GenerateEnumerableMapping(currentDepth, options, customMapping, typeMapping, destinationMember, sourceMember); } else { // Create a deeper mapping for a 'regular' type. GenerateComplexTypeMapping(currentDepth, options, customMapping, typeMapping, destinationMember, sourceMember); } } // All we have is a destination member and a custom expression // that gives the destination member a value. Good enough! else if (customExpression != null) { typeMapping.ProposedMappings.Add ( new ProposedMemberMapping { SourceMember = null, DestinationMember = destinationMember } ); } } // Don't cache the typemapping when this flag has been set. // That happens when the maximum depth was reached during the mapping // for this particular type and we didn't explore the full depth // of the type. We don't wanna reuse this typemapping at a later time // because the mapping might be for something completely different // at a depth at which the full depth CAN be explored. if (!typeMapping.DoNotCache) { mappingCache[pair] = typeMapping; } typeStack.Pop(); return(typeMapping); }
static void Main(string[] args) { CustomMapping.Example(); }