Example #1
0
        internal static void GenerateCopyFieldsExpressions(IEnumerable <FieldInfo> fields,
                                                           ParameterExpression source,
                                                           ParameterExpression clone,
                                                           List <Expression> expressions,
                                                           ParameterExpression refTrackerParam,
                                                           ParameterExpression clonedItem)
        {
            foreach (var field in fields)
            {
                var cloneField  = Expression.Field(clone, field);
                var sourceField = Expression.Field(source, field);
                if (field.FieldType.IsPrimitive || field.FieldType.IsValueType || (field.FieldType == typeof(string)))
                {
                    if (field.IsInitOnly)
                    {
                        expressions.Add(Expression.Call(CopyReadOnlyFieldMethodInfo.GetMethodInfo(),
                                                        Expression.Constant(field),
                                                        Expression.Convert(sourceField, typeof(object)),
                                                        clone));
                    }
                    else
                    {
                        var from = sourceField;
                        var to   = cloneField;
                        expressions.Add(Expression.Assign(to, from));
                    }
                }
                else
                {
                    var es = new List <Expression>();
                    es.Add(Expression.Assign(clonedItem, Expression.Call(SerializerMih.PrepareObjectForSerialization(), sourceField)));
                    es.Add(Expression.Assign(clonedItem, CallCopyExpression(clonedItem, refTrackerParam, Expression.Constant(field.FieldType))));

                    if (IQueryableCloner.IsGenericIQueryableType(field.FieldType))
                    {
                        Type queryableInterface  = IQueryableCloner.GetInterfaceType(field.FieldType, typeof(IQueryable <>));
                        var  genericArgumentType = queryableInterface.GetGenericArguments()[0];

                        var copy2 = Expression.Convert(clonedItem, field.FieldType);
                        var m     = Expression.Call(typeof(Queryable), "AsQueryable", new Type[] { genericArgumentType }, Expression.Convert(copy2, typeof(IEnumerable <>).MakeGenericType(genericArgumentType)));
                        es.Add(Expression.Assign(clonedItem, m));
                    }

                    if (field.FieldType == typeof(IQueryable))
                    {
                        es.Add(Expression.Assign(clonedItem, Expression.Call(IQueryableMih.ConvertToNonGenericQueryable(), clonedItem)));
                    }

                    if (field.IsInitOnly)
                    {
                        Func <Expression, Expression> assignExpr = exx => Expression.Call(CopyReadOnlyFieldMethodInfo.GetMethodInfo(),
                                                                                          Expression.Constant(field),
                                                                                          Expression.Convert(exx, typeof(object)),
                                                                                          clone);

                        var assignNullExpr = Expression.Call(CopyReadOnlyFieldMethodInfo.GetMethodInfo(),
                                                             Expression.Constant(field),
                                                             Expression.Constant(null, typeof(object)),
                                                             clone);

                        es.Add(clonedItem);
                        var conditionalExpression = Expression.IfThenElse(Expression.NotEqual(sourceField, Expression.Constant(null)),
                                                                          assignExpr(Expression.Block(es)),
                                                                          assignNullExpr);

                        expressions.Add(ObjectCloner.GenerateNullTrackedOrUntrackedExpression(sourceField,
                                                                                              cloneField,
                                                                                              field.FieldType,
                                                                                              refTrackerParam,
                                                                                              conditionalExpression,
                                                                                              trackedExpression: assignExpr)); // todo refactor this horrible method
                    }
                    else
                    {
                        es.Add(Expression.Assign(cloneField, Expression.Convert(clonedItem, field.FieldType)));


                        var conditionalExpression = Expression.IfThenElse(Expression.Equal(sourceField, Expression.Constant(null)),
                                                                          Expression.Assign(cloneField, Expression.Constant(null, field.FieldType)),
                                                                          Expression.Block(es));

                        expressions.Add(ObjectCloner.GenerateNullTrackedOrUntrackedExpression(sourceField,
                                                                                              cloneField,
                                                                                              field.FieldType,
                                                                                              refTrackerParam,
                                                                                              conditionalExpression));
                    }
                }
            }
        }
Example #2
0
        internal static void GenerateReadFieldsExpression(Type type,
                                                          FieldInfo[] fields,
                                                          ParameterExpression inputStream,
                                                          ParameterExpression objTracker,
                                                          Dictionary <Type, ParameterExpression> temporaryVariables,
                                                          List <ParameterExpression> variables,
                                                          ParameterExpression newInstance,
                                                          List <Expression> notTrackedExpressions,
                                                          ParameterExpression typeExpr,
                                                          ParameterExpression typeName,
                                                          ParameterExpression typeHashCode,
                                                          ParameterExpression deserializer)
        {
            Func <Type, ParameterExpression> getTempVar = t =>
            {
                ParameterExpression tmpVar;
                if (!temporaryVariables.TryGetValue(t,
                                                    out tmpVar))
                {
                    tmpVar = Expression.Parameter(t);
                    temporaryVariables.Add(t,
                                           tmpVar);
                    variables.Add(tmpVar);
                }

                return(tmpVar);
            };


            foreach (var fieldInfo in fields)
            {
                var fieldValueExpr = Expression.Field(newInstance,
                                                      fieldInfo);

                if (fieldInfo.FieldType == typeof(string))
                {
                    if (fieldInfo.IsInitOnly)
                    {
                        var tmpVar = getTempVar(fieldInfo.FieldType);
                        notTrackedExpressions.Add(Expression.Assign(tmpVar, GenerateStringExpression(inputStream, objTracker)));
                        notTrackedExpressions.Add(Expression.Call(CopyReadOnlyFieldMethodInfo.GetMethodInfo(),
                                                                  Expression.Constant(fieldInfo),
                                                                  Expression.Convert(tmpVar,
                                                                                     typeof(object)),
                                                                  newInstance));
                    }
                    else
                    {
                        var tmpVar = getTempVar(fieldInfo.FieldType);
                        notTrackedExpressions.Add(Expression.Assign(tmpVar, GenerateStringExpression(inputStream, objTracker)));
                        notTrackedExpressions.Add(Expression.Assign(fieldValueExpr, tmpVar));
                    }
                }
                else if (fieldInfo.FieldType.IsPrimitive || fieldInfo.FieldType.IsValueType)
                {
                    var        primitiveReader = GetPrimitiveReader(fieldInfo.FieldType);
                    Expression newValue;

                    if (primitiveReader == null)
                    {
                        var primitiveDeserializer = GetTypeDeserializer(fieldInfo.FieldType);
                        newValue = Expression.Convert(Expression.Invoke(Expression.Constant(primitiveDeserializer), inputStream, objTracker), fieldInfo.FieldType);
                    }
                    else
                    {
                        newValue = primitiveReader(inputStream, objTracker);

                        if (fieldInfo.FieldType == typeof(byte) ||
                            fieldInfo.FieldType == typeof(sbyte) ||
                            fieldInfo.FieldType == typeof(byte?) ||
                            fieldInfo.FieldType == typeof(sbyte?) ||
                            IsEnumOrNullableEnum(fieldInfo.FieldType))
                        {
                            newValue = Expression.Convert(newValue, fieldInfo.FieldType);
                        }
                    }

                    var tmpVar = getTempVar(fieldInfo.FieldType);
                    notTrackedExpressions.Add(Expression.Assign(tmpVar,
                                                                newValue));

                    if (fieldInfo.IsInitOnly)
                    {
                        notTrackedExpressions.Add(Expression.Call(CopyReadOnlyFieldMethodInfo.GetMethodInfo(), Expression.Constant(fieldInfo), Expression.Convert(tmpVar, typeof(object)), newInstance));
                    }
                    else
                    {
                        notTrackedExpressions.Add(Expression.Assign(fieldValueExpr, tmpVar));
                    }
                }
                else
                {
                    if (fieldInfo.IsInitOnly)
                    {
                        var tmpVar = getTempVar(typeof(object));
                        notTrackedExpressions.Add(GetReadClassExpression(inputStream, objTracker, tmpVar, typeExpr, typeName, typeHashCode, deserializer, fieldInfo.FieldType));
                        notTrackedExpressions.Add(Expression.Call(CopyReadOnlyFieldMethodInfo.GetMethodInfo(),
                                                                  Expression.Constant(fieldInfo),
                                                                  tmpVar,
                                                                  newInstance));
                    }
                    else
                    {
                        notTrackedExpressions.Add(GetReadClassExpression(inputStream, objTracker, fieldValueExpr, typeExpr, typeName, typeHashCode, deserializer, fieldInfo.FieldType));
                    }
                }
            }
        }