static TD MapCrossReferences( MappingContext ctx, TS source, Func <TS, TD> func, Func <object, object> getCurrent, Action <object, object> setCurrent) { if (source == null) { return(null); } object dest; List <Action <object, object> > list; if (ctx.Objects.TryGetValue(source, out dest)) { if (dest == null) { if (ctx.Crosses == null) { ctx.Crosses = new Dictionary <object, List <Action <object, object> > >(); } if (!ctx.Crosses.TryGetValue(source, out list)) { ctx.Crosses[source] = list = new List <Action <object, object> >(); } var getParent = ctx.GetParent; Action <object, object> setter = (obj, value) => setCurrent(getParent(obj), value); list.Add(setter); } return((TD)dest); } var currParent = ctx.GetParent; ctx.GetParent = p => getCurrent(currParent(p)); ctx.Objects.Add(source, null); ctx.Objects[source] = dest = func(source); ctx.GetParent = currParent; if (ctx.Crosses != null && ctx.Crosses.TryGetValue(source, out list)) { if (ctx.CrossActions == null) { ctx.CrossActions = new List <Action <object> >(); } foreach (var action in list) { var setValue = action; Action <object> f = parent => setValue(parent, dest); ctx.CrossActions.Add(f); } ctx.Crosses.Remove(source); } return((TD)dest); }
public Func <TSource, TDest> GetMapper() { if (typeof(TSource) == typeof(TDest) && !DeepCopy) { return(s => (TDest)(object)s); } if (TypeHelper.IsAbstractClass(typeof(TSource)) || TypeHelper.IsAbstractClass(typeof(TDest))) { var st = TypeHelper.IsAbstractClass(typeof(TSource)) ? TypeAccessor <TSource> .Instance.Type : typeof(TSource); var dt = TypeHelper.IsAbstractClass(typeof(TDest)) ? TypeAccessor <TDest> .Instance.Type : typeof(TDest); var type = typeof(AbstractHelper <,>).MakeGenericType(typeof(TSource), typeof(TDest), st, dt); return(((IAbstractHelper)Activator.CreateInstance(type)).GetMapper(_parameters)); } var parm = Expression.Parameter(typeof(TSource), "src"); var expr = GetValueMapper( parm, typeof(TDest), true, _parameters.MappingSchema.GetNullValue(typeof(TDest)), _parameters.MappingSchema.GetMapValues(typeof(TDest)), _parameters.MappingSchema.GetDefaultValue(typeof(TDest)), _parameters.MappingSchema.GetMapValues(typeof(TSource))); if (_parameters.ContextParameterUsed) { var l = Expression.Lambda <Func <TSource, MappingContext, TDest> >(expr, parm, _parameters.MappingContext); var f = l.Compile(); if (!_parameters.UseContext) { return(s => f(s, null)); } return(s => { var ctx = new MappingContext { Objects = new Dictionary <object, object>(10) { { s, null } }, GetParent = p => p, }; var dest = f(s, ctx); if (ctx.CrossActions != null) { foreach (var circle in ctx.CrossActions) { circle(dest); } } if (ctx.Crosses != null) { List <Action <object, object> > list; if (ctx.Crosses.TryGetValue(s, out list)) { foreach (var action in list) { action(dest, dest); } } } return dest; }); } var lambda = Expression.Lambda <Func <TSource, TDest> >(expr, parm); return(lambda.Compile()); }
public Func <TSource, TDest> GetMapper() { if (typeof(TSource) == typeof(TDest) && !DeepCopy) { return(s => (TDest)(object)s); } var parm = Expression.Parameter(typeof(TSource), "src"); var expr = GetValueMapper( parm, typeof(TDest), true, _parameters.MappingSchema.GetNullValue(typeof(TDest)), _parameters.MappingSchema.GetMapValues(typeof(TDest)), _parameters.MappingSchema.GetDefaultValue(typeof(TDest)), _parameters.MappingSchema.GetMapValues(typeof(TSource))); if (_parameters.ContextParameterUsed) { var l = Expression.Lambda <Func <TSource, MappingContext, TDest> >(expr, parm, _parameters.MappingContext); var f = l.Compile(); if (!_parameters.UseContext) { return(s => f(s, null)); } return(s => { var ctx = new MappingContext { Objects = new Dictionary <object, object>(10) { { s, null } }, GetParent = p => p, }; var dest = f(s, ctx); if (ctx.CrossActions != null) { foreach (var circle in ctx.CrossActions) { circle(dest); } } if (ctx.Crosses != null) { List <Action <object, object> > list; if (ctx.Crosses.TryGetValue(s, out list)) { foreach (var action in list) { action(dest, dest); } } } return dest; }); } var lambda = Expression.Lambda <Func <TSource, TDest> >(expr, parm); return(lambda.Compile()); }