internal static LambdaExpression GetMapInternal(Type tSource, Type tDest, bool resetCallContext, IObjectContext context = null) { var key = MapperKey.Get(tSource, tDest); LambdaExpression expression = null; if (context == null) { context = CreateContext(); } GetMapCallContext callContext = null; if (resetCallContext || !context.TryGetContext <GetMapCallContext>(out callContext)) { context.SetContext <GetMapCallContext>(callContext = new GetMapCallContext()); } if (callContext.TryGet(key, out expression)) { return(expression); } var mapCreator = GetMapCreator(key); var expBuilder = mapCreator.CreateUnexpandedMap(context); var exp = expBuilder.Build(); expression = ExpandInternal(exp, context); return(callContext.Set(key, expression)); }
/// <summary> /// Creates a dynamic lambda expression that maps one type to another. Use GetMap() to obtain the expression. /// <para />Mapping conventions: /// <para />* Auto-maps properties with matching names. /// <para />* Auto-maps second level properties prefixed with the first level property name. (i.e. dest.OrganisationName matched to source.Organisation.Name ) /// <para />* When auto-mapping, the property types must match or there must be an existing map for them, otherwise the property will be ignored. /// <para />* Mapping conventions can be overriden via customMapping parameter. /// <para />* Expressions can be reused by calling InvokeMap() when overriding a property. (e.g. (TSource s) => new TDest(){ Property = s.AnotherProperty.InvokeMap<Ta,Tb>() } ) /// </summary> /// <typeparam name="TSource">The source type</typeparam> /// <typeparam name="TDest">The destination type</typeparam> /// <param name="customMapping">A mapping expression which overrides the default mapping conventions for each property. <para /> (e.g. LinqMapper.CreateMap<Tx,Ty>((Tx x) => new Ty(){ Id = x.Id + 1 }); )</param> public static ILinqMapperSyntax <TSource, TDest> CreateMap <TSource, TDest>(Expression <Func <TSource, TDest> > customMapping = null) where TDest : class, new() { var key = MapperKey.Get(typeof(TSource), typeof(TDest)); if (_Maps.ContainsKey(key)) { throw new ApplicationException(String.Format("Linq map already exists for types [{0}; {1}]", key.TSource.FullName, key.TDest.FullName)); } _Maps[key] = new ExtendedMapCreator <TSource, TDest>(customMapping); return(new LinqMapperSyntax <TSource, TDest>(key)); }
private static Expression TryCreateMappingExpression(Expression sourceExpression, Type sourceType, Type destType, bool nullCheckForClass) { var key = MapperKey.Get(sourceType, destType); if (_Maps.ContainsKey(key)) { //Dynamically creates: //sourceExpression.InvokeMap<TSource, TDest>() OR sourceExpression.InvokeOptionalMap<TSource, TDest>() when sourceType is a class and null check is enabled var invokeMapMethodInfo = sourceType.IsClass && nullCheckForClass? invokeOptionalMapTemplate.MakeGenericMethod(key.TSource, key.TDest) : invokeMapTemplate.MakeGenericMethod(key.TSource, key.TDest); return(Expression.Call(invokeMapMethodInfo, sourceExpression)); } else if (sourceType == destType && IsPrimitive(sourceType)) { //the sourceExpression is compatible with the destination return(sourceExpression); } return(TryCreateMappingNullableDest(sourceExpression, sourceType, destType) ?? TryCreateMappingNullableSource(sourceExpression, sourceType, destType) ?? TryCreateMappingCollection(sourceExpression, sourceType, destType)); }
public CastBaseMapCreator() { _basekey = MapperKey.Get(typeof(TBaseSource), typeof(TBaseDest)); }