private void CompileNonGenericCustomTypeMapper(Type srcType, Type dstType, ICustomTypeMapper typeMapper, long cacheKey) { var sourceExpression = Expression.Parameter(typeof(object), "src"); var destinationExpression = Expression.Parameter(typeof(object), "dst"); var srcConverted = Expression.Convert(sourceExpression, srcType); var srcTypedExp = Expression.Variable(srcType, "srcTyped"); var srcAssigned = Expression.Assign(srcTypedExp, srcConverted); var dstConverted = Expression.Convert(destinationExpression, dstType); var dstTypedExp = Expression.Variable(dstType, "dstTyped"); var dstAssigned = Expression.Assign(dstTypedExp, Expression.Condition(Expression.Equal(destinationExpression, Expression.Constant(null)), Expression.Default(dstType), dstConverted)); var customGenericType = typeof(ICustomTypeMapper <,>).MakeGenericType(srcType, dstType); var castToCustomGeneric = Expression.Convert(Expression.Constant(typeMapper, typeof(ICustomTypeMapper)), customGenericType); var genVariable = Expression.Variable(customGenericType); var assignExp = Expression.Assign(genVariable, castToCustomGeneric); var methodInfo = customGenericType.GetInfo().GetMethod("Map"); var genericMappingContextType = typeof(DefaultMappingContext <,>).MakeGenericType(srcType, dstType); var newMappingContextExp = Expression.New(genericMappingContextType); var contextVarExp = Expression.Variable(genericMappingContextType, $"context{Guid.NewGuid()}"); var assignContextExp = Expression.Assign(contextVarExp, newMappingContextExp); var sourceExp = Expression.Property(contextVarExp, "Source"); var sourceAssignedExp = Expression.Assign(sourceExp, srcTypedExp); var destExp = Expression.Property(contextVarExp, "Destination"); var destAssignedExp = Expression.Assign(destExp, dstTypedExp); //var destinationAssignedExp = Expression.Assign(destinationExpression, dstTypedExp); var mapCall = Expression.Call(genVariable, methodInfo, contextVarExp); var resultVarExp = Expression.Variable(typeof(object), "result"); var resultAssignExp = Expression.Assign(resultVarExp, Expression.Convert(mapCall, typeof(object))); var blockExpression = Expression.Block(new[] { srcTypedExp, dstTypedExp, genVariable, contextVarExp, resultVarExp }, srcAssigned, dstAssigned, assignExp, assignContextExp, sourceAssignedExp, destAssignedExp, /*destinationAssignedExp,*/ resultAssignExp, resultVarExp); var lambda = Expression.Lambda <Func <object, object, object> >(blockExpression, sourceExpression, destinationExpression); this._customTypeMapperCache[cacheKey] = lambda.Compile(); }
public static IProperty CustomType <TOut>(this IProperty property, ICustomTypeMapper <TOut> customTypeMapper) { var p = ((IProperty <TOut>)property); if (p.CustomTypeMapper != null) { return(property); } p.CustomTypeMapper = customTypeMapper; p.FromDbConvertor = customTypeMapper.FromDb; p.ToParameter = i => customTypeMapper.ToParameter((TOut)i); var valueAccessor = p.ValueAccessor; p.ValueAccessor = i => customTypeMapper.ToParameter((TOut)valueAccessor(i)); return(property); }
protected void CompileGenericCustomTypeMapper(Type srcType, Type dstType, ICustomTypeMapper typeMapper, long cacheKey) { if (this.CustomTypeMapperExpCache.ContainsKey(cacheKey)) { return; } var srcTypedExp = Expression.Variable(srcType, "srcTyped"); var dstTypedExp = Expression.Variable(dstType, "dstTyped"); var customGenericType = typeof(ICustomTypeMapper <,>).MakeGenericType(srcType, dstType); var castToCustomGeneric = Expression.Convert( Expression.Constant(typeMapper, typeof(ICustomTypeMapper)), customGenericType); var genVariable = Expression.Variable(customGenericType); var assignExp = Expression.Assign(genVariable, castToCustomGeneric); var methodInfo = customGenericType.GetInfo().GetMethod("Map"); var genericMappingContext = typeof(DefaultMappingContext <,>).MakeGenericType(srcType, dstType); var newMappingContextExp = Expression.New(genericMappingContext); var contextVarExp = Expression.Variable(genericMappingContext, string.Format("context{0}", Guid.NewGuid())); var assignContextExp = Expression.Assign(contextVarExp, newMappingContextExp); var sourceExp = Expression.Property(contextVarExp, "Source"); var sourceAssignedExp = Expression.Assign(sourceExp, srcTypedExp); var destExp = Expression.Property(contextVarExp, "Destination"); var destAssignedExp = Expression.Assign(destExp, dstTypedExp); var mapCall = Expression.Call(genVariable, methodInfo, contextVarExp); //var resultVarExp = Expression.Variable(dstType, "result"); //var resultAssignExp = Expression.Assign(resultVarExp, mapCall); var resultAssignExp = Expression.Assign(dstTypedExp, mapCall); var blockExpression = Expression.Block( new[] { genVariable, contextVarExp }, assignExp, assignContextExp, sourceAssignedExp, destAssignedExp, resultAssignExp); this.CustomTypeMapperExpCache[cacheKey] = Expression.Block(new ParameterExpression[] { }, blockExpression); }
public TN Map <T, TN>(T src, ICustomTypeMapper <T, TN> customMapper, TN dest) { return(customMapper.Map(new DefaultMappingContext <T, TN> { Source = src, Destination = dest })); }
public static TN Map <T, TN>(T src, ICustomTypeMapper <T, TN> customMapper, TN dest = default(TN)) { return(Instance.Map(src, customMapper, dest)); }