/// <summary> /// Construct a new chain given a member name and a child chain. /// </summary> /// <param name="memberName"></param> /// <param name="childChain"></param> private IncludeChain(string memberName, IncludeChain childChain) { _Includes = new Dictionary <string, IncludeChain>() { { memberName, childChain } }; }
public static IncludeChain CreateFromLambdas(LambdaExpression[] inclusions) { IncludeChain finalIncludeChain = NullValue; if (inclusions != null && inclusions.Length > 0) { finalIncludeChain = IncludeChain.CreateFromLambda(inclusions[0]); for (int i = 1; i < inclusions.Length; i++) { finalIncludeChain.Merge(IncludeChain.CreateFromLambda(inclusions[i])); } } return(finalIncludeChain); }
/// <summary> /// Merge the current IncludeChain with the specified one. The two chains must target the same type. /// </summary> /// <param name="chain"></param> protected virtual void Merge(IncludeChain chain) { foreach (var kp in chain.Includes) { IncludeChain originalChain; if (Includes.TryGetValue(kp.Key, out originalChain) && (originalChain != NullValue)) { originalChain.Merge(kp.Value); } else { Includes[kp.Key] = kp.Value; } } }
/// <summary> /// Creates a chain from an Expression and a child chain. /// </summary> /// <param name="expression"></param> /// <param name="childChain"></param> /// <returns></returns> private static IncludeChain _CreateFromLambda(Expression expression, IncludeChain childChain) { MemberExpression me = expression as MemberExpression; if (me != null) { ParameterExpression pe = me.Expression as ParameterExpression; if (pe != null) { return(new IncludeChain(me.Member.Name, childChain)); } return(_CreateFromLambda(me.Expression, new IncludeChain(me.Member.Name, childChain))); } MethodCallExpression mc = expression as MethodCallExpression; if (mc != null) { if (mc.Method.Name == "Select") { return(_CreateFromLambda(mc.Arguments[0], _CreateFromLambda((mc.Arguments[1] as LambdaExpression).Body, childChain))); } } UnaryExpression ue = expression as UnaryExpression; if (ue != null) { if (ue.NodeType == ExpressionType.Convert || ue.NodeType == ExpressionType.TypeAs) { if (ue.Operand is MemberExpression) { return(_CreateFromLambda(ue.Operand, childChain)); } return(childChain); } } throw new Exception(String.Format("Unsupported linq expression: {0}", expression.ToString())); }
private static void _Fill <TSource, TTarget>(TSource source, TTarget target, MapMode mapMode, IncludeChain chain) { if (source == null) { return; } bool CacheInitializedInThisCall = MapperCache.Cache == null; if (CacheInitializedInThisCall) { MapperCache.Cache = new Dictionary <Tuple <object, Type>, object>(); } Action <TSource, TTarget, IncludeChain> builder; switch (mapMode) { case MapMode.All: builder = PolymorphismManager <TSource, TTarget> .FillerModeAll.Value; break; case MapMode.Include: builder = PolymorphismManager <TSource, TTarget> .FillerModeInclusion.Value; break; case MapMode.Exclude: builder = PolymorphismManager <TSource, TTarget> .FillerModeExclusion.Value; break; default: throw new NotSupportedException(); } try { if (builder == null) { throw new NotMappedException(typeof(TSource), typeof(TTarget)); } builder.Invoke(source, target, chain); } finally { if (CacheInitializedInThisCall) { MapperCache.Cache = null; } } }
/// <summary> /// Fill the specified target object given the source object. /// Relational objects that appear in the exclusions parameter will be ignored. /// </summary> /// <param name="source">Source object.</param> /// <param name="target">Target object to fill.</param> /// <param name="exclusions">Linq expression representing the relational objects to ignore.</param> /// <returns></returns> public static void FillExclude <TSource, TTarget>(TSource source, TTarget target, params Expression <Func <TTarget, object> >[] exclusions) { _Fill(source, target, MapMode.Exclude, IncludeChain.CreateFromLambdas(exclusions)); }
/// <summary> /// Create a mapped object given the source object. /// Relational objects that appear in the exclusions parameter will be ignored. /// </summary> /// <typeparam name="TTarget">Type of the target object</typeparam> /// <param name="source">Source object</param> /// <param name="exclusions">Linq expression representing the relational objects to ignore.</param> /// <returns>The generated target object.</returns> public static TTarget MapExclude <TSource, TTarget>(TSource source, params Expression <Func <TTarget, object> >[] exclusions) { return(_Map <TSource, TTarget>(source, MapMode.Exclude, IncludeChain.CreateFromLambdas(exclusions))); }
internal static TTarget _Map <TSource, TTarget>(TSource source, MapMode mapMode, IncludeChain chain) { TTarget result = default(TTarget); bool CacheInitializedInThisCall = MapperCache.Cache == null; if (CacheInitializedInThisCall) { MapperCache.Cache = new Dictionary <Tuple <object, Type>, object>(); } Func <TSource, IncludeChain, TTarget> builder; switch (mapMode) { case MapMode.All: builder = PolymorphismManager <TSource, TTarget> .CreatorModeAll.Value; break; case MapMode.Include: builder = PolymorphismManager <TSource, TTarget> .CreatorModeInclusion.Value; break; case MapMode.Exclude: builder = PolymorphismManager <TSource, TTarget> .CreatorModeExclusion.Value; break; default: throw new NotSupportedException(); } try { if (builder == null) { throw new NotMappedException(typeof(TSource), typeof(TTarget)); } result = builder(source, chain); } finally { if (CacheInitializedInThisCall) { MapperCache.Cache = null; } } return(result); }