protected void AddTypeRuleOptimized <T>( Expression <Func <StringBuilder, T, bool> > funcExpression ) { var methodInfo = JsonChainTools.GetMethodInfoExpr(funcExpression, compile); var type = typeof(T); var formatterDelegateType = typeof(Func <, ,>).MakeGenericType(typeof(StringBuilder), type, typeof(bool)); var @delegate = methodInfo.CreateDelegate(formatterDelegateType); AddTypeRuleForCurrentInclude <T>(@delegate, nullSerializer, handleNullProperty, internalNodeOptions); }
public static Func <StringBuilder, IEnumerable <T>, bool> ComposeEnumerableSerializer <T>( ChainNode root , Func <ChainNode, SerializerOptions> getSerializerOptions , Func <ChainNode, InternalNodeOptions> getInternalNodeOptions , bool rootHandleNull , bool rootHandleEmptyLiteral , Func <LambdaExpression, Delegate> compile , bool doCompileInnerLambdas = true) { Func <StringBuilder, IEnumerable <T>, bool> @value = null; var enumerableType = typeof(IEnumerable <T>); var expressions = JsonChainTools.CreateSerializsPair(root, /* node.Type,*/ getSerializerOptions, getInternalNodeOptions, compile, doCompileInnerLambdas); ConstantExpression nullSerializerExpression = null; if (JsonChainTools.IsNullable(root.Type)) { if (expressions.NullSerializer == null) { throw new NotSupportedException($"Null serializer is not setuped for root node"); } nullSerializerExpression = JsonChainTools.CreateSerializeNullConstant(expressions.NullSerializer); } var sbExpression = Expression.Parameter(typeof(StringBuilder), "sb"); var tExpression = Expression.Parameter(enumerableType, "t"); var isNullableStruct = JsonChainTools.IsNullableStruct(root.Type); var serializationType = Nullable.GetUnderlyingType(root.Type) ?? root.Type; var methodCallExpression = JsonChainTools.CreateSerializeArrayMethodCall( serializationType, isNullableStruct, expressions.SerializerExpression, nullSerializerExpression, sbExpression, tExpression, rootHandleEmptyLiteral); Expression serializeConditionalExpression; if (rootHandleNull) { var serializers = getInternalNodeOptions(root); var rootNullMethodInfo = serializers.NullSerializer.GetMethodInfo(); MethodCallExpression nullCallExpression = Expression.Call(rootNullMethodInfo, new Expression[] { sbExpression }); serializeConditionalExpression = Expression.Condition( Expression.Equal(tExpression, Expression.Constant(null)), nullCallExpression, methodCallExpression ); } else { serializeConditionalExpression = Expression.Condition( Expression.Equal(tExpression, Expression.Constant(null)), Expression.Constant(false), methodCallExpression ); } var serializeArrayLambda = Expression.Lambda(serializeConditionalExpression, new[] { sbExpression, tExpression }); @value = (Func <StringBuilder, IEnumerable <T>, bool>)compile(serializeArrayLambda); return(@value); }
public static Func <StringBuilder, T, bool> ComposeSerializer <T>( ChainNode root , Func <ChainNode, SerializerOptions> getSerializerOptions , Func <ChainNode, InternalNodeOptions> getInternalNodeOptions , bool rootHandleNull , bool rootHandleEmptyLiteral , Func <LambdaExpression, Delegate> compile , bool doCompileInnerLambdas ) { Func <StringBuilder, T, bool> @value = null; Expression serializeExpression; var objectType = typeof(T); var sbParameterExpression = Expression.Parameter(typeof(StringBuilder), "sb"); var tParameterExpression = Expression.Parameter(objectType, "t"); if (root.Children.Count == 0) // leaf { var serializerSet = getSerializerOptions(root); var isNullableStruct = JsonChainTools.IsNullableStruct(root.Type); if (isNullableStruct != null && isNullableStruct.Value == false) { var delegateMethodInfo = serializerSet.Serializer.GetMethodInfo(); var target = serializerSet.Serializer.Target; serializeExpression = Expression.Call(target != null ? Expression.Constant(target) : null, delegateMethodInfo, new Expression[] { sbParameterExpression, tParameterExpression }); } else { Expression nullCallExpression; if (rootHandleNull) { if (serializerSet.NullSerializer == null) { throw new NotSupportedException($"Null serializer is not setuped for root node"); } var rootNullSerializeMethodInfo = serializerSet.NullSerializer.GetMethodInfo(); nullCallExpression = Expression.Call(rootNullSerializeMethodInfo, new Expression[] { sbParameterExpression }); } else { nullCallExpression = Expression.Constant(false); } if (isNullableStruct == null) // class { var @delegate = serializerSet.Serializer.GetMethodInfo(); var methodCallExpression = Expression.Call(@delegate, new Expression[] { sbParameterExpression, tParameterExpression }); serializeExpression = Expression.Condition( Expression.Equal(tParameterExpression, Expression.Constant(null)), nullCallExpression, methodCallExpression ); } else if (isNullableStruct.Value) { var @delegate = serializerSet.Serializer.GetMethodInfo(); var hasValueExpression = Expression.Property(tParameterExpression, "HasValue"); var valueExpression = Expression.Property(tParameterExpression, "Value"); var methodCallExpression = Expression.Call(@delegate, new Expression[] { sbParameterExpression, valueExpression }); serializeExpression = Expression.Condition( hasValueExpression, methodCallExpression, nullCallExpression ); } else { throw new NotSupportedException(); } } } else // internal (note: currently can't be nullable struct) { var serializerSet = getInternalNodeOptions(root); var parentObjectAsArray = serializerSet.ObjectAsArray; var properies = new List <Expression>(); foreach (var c in root.Children) { var n = c.Value; JsonChainTools.ConfigureSerializeProperty(n, root.Type, parentObjectAsArray, properies, getSerializerOptions, getInternalNodeOptions, compile, doCompileInnerLambdas); } var methodCallExpression = JsonChainTools.CreateSerializeMethodCallExpression(sbParameterExpression, tParameterExpression, objectType, parentObjectAsArray, rootHandleEmptyLiteral, properies.ToArray()); if (JsonChainTools.IsNullable(root.Type)) { if (rootHandleNull) { if (serializerSet.NullSerializer == null) { throw new NotSupportedException($"Null serializer is not setuped for internal node '{root.FindLinkedRootXPath()}' "); } var rootNullSerializeMethodInfo = serializerSet.NullSerializer.GetMethodInfo(); MethodCallExpression nullCallExpression = Expression.Call(rootNullSerializeMethodInfo, new Expression[] { sbParameterExpression }); serializeExpression = Expression.Condition( Expression.Equal(tParameterExpression, Expression.Constant(null)), nullCallExpression, methodCallExpression ); } else { serializeExpression = Expression.Condition( Expression.Equal(tParameterExpression, Expression.Constant(null)), Expression.Constant(false), methodCallExpression ); } } else // struct { serializeExpression = methodCallExpression; } } var serializeLambda = Expression.Lambda(serializeExpression, new[] { sbParameterExpression, tParameterExpression }); @value = (Func <StringBuilder, T, bool>)compile(serializeLambda); return(@value); }