示例#1
0
        private Func <ParameterExpression, Expression> CloneArrayElementDelegate(CloneExpressionContext context)
        {
            Type elementType = context
                               .SourceEntity
                               .Type
                               .GetElementType();
            PropertyInfo indexProperty = typeof(IList <>)
                                         .MakeGenericType(elementType)
                                         .GetProperty(IndexPropertyName);

            if (PrimitiveTypes.Contains(elementType))
            {
                return (iterator) =>
                       {
                           Expression getElementExpression = ExpressionFactory.Call(context.SourceEntity, indexProperty.GetMethod, iterator);
                           return ExpressionFactory.Call(context.TargetEntity, indexProperty.SetMethod, iterator, getElementExpression);
                       }
            }
            ;
            else
            {
                return (iterator) =>
                       {
                           Expression getElementExpression = ExpressionFactory.Call(context.SourceEntity, indexProperty.GetMethod, iterator);
                           MethodInfo cloneMethod          = CloneMethod.MakeGenericMethod(elementType);
                           Expression clonedElement        = ExpressionFactory.Call(context.CloneFactory, cloneMethod, getElementExpression);
                           return ExpressionFactory.Call(context.TargetEntity, indexProperty.SetMethod, iterator, clonedElement);
                       }
            };
        }
示例#2
0
        private void ClonePrimitiveProperty(IExpressionBuilder expressionBuilder, CloneExpressionContext parameters, PropertyInfo property)
        {
            Expression sourceValue = ExpressionFactory.Call(parameters.SourceEntity, property.GetMethod);

            expressionBuilder.SetProperty(
                parameters.TargetEntity,
                property,
                sourceValue);
        }
示例#3
0
        private void CloneComplexProperty(IExpressionBuilder expressionBuilder, CloneExpressionContext parameters, PropertyInfo property)
        {
            MethodInfo cloneMethod  = CloneMethod.MakeGenericMethod(property.PropertyType);
            Expression complexValue = ExpressionFactory.Call(parameters.SourceEntity, property.GetMethod);
            Expression subClone     = ExpressionFactory.Call(parameters.CloneFactory, cloneMethod, complexValue);

            expressionBuilder.SetProperty(
                parameters.TargetEntity,
                property,
                subClone);
        }
示例#4
0
 private void CloneProperty(IExpressionBuilder expressionBuilder, CloneExpressionContext parameters, PropertyInfo property)
 {
     if (PrimitiveTypes.Contains(property.PropertyType))
     {
         ClonePrimitiveProperty(expressionBuilder, parameters, property);
     }
     else
     {
         CloneComplexProperty(expressionBuilder, parameters, property);
     }
 }
示例#5
0
        private CloneDelegate <TEntity> AssembleExpression <TEntity>(IExpressionBuilder expressionBuilder)
            where TEntity : class
        {
            CloneExpressionContext context = new CloneExpressionContext
            {
                SourceEntity = expressionBuilder.AddParameter <TEntity>(nameof(CloneExpressionContext.SourceEntity)),
                CloneFactory = expressionBuilder.AddParameter <ICloneFactory>(nameof(CloneExpressionContext.CloneFactory)),
            };

            if (CollectionTypes.Any(collectionType => IsCollectionType(collectionType, typeof(TEntity))))
            {
                AddCollectionExpressions <TEntity>(expressionBuilder, context);
            }
            else
            {
                AddCloneExpressions <TEntity>(expressionBuilder, context);
            }

            expressionBuilder.ReturnObject(context.TargetEntity);

            return(expressionBuilder.Build <CloneDelegate <TEntity> >());
        }
示例#6
0
 private void AddCloneExpressions <TEntity>(IExpressionBuilder expressionBuilder, CloneExpressionContext parameters)
 {
     parameters.TargetEntity = expressionBuilder.CreateObject <TEntity>(nameof(CloneExpressionContext.TargetEntity));
     foreach (PropertyInfo cloneableProperty in CloneableProperties(typeof(TEntity)))
     {
         CloneProperty(expressionBuilder, parameters, cloneableProperty);
     }
 }
示例#7
0
        private Func <ParameterExpression, Expression> CloneListElementDelegate(IExpressionBuilder expressionBuilder, CloneExpressionContext context)
        {
            Type elementType = context
                               .SourceEntity
                               .Type
                               .GenericTypeArguments
                               .Single();
            PropertyInfo indexProperty = typeof(IList <>)
                                         .MakeGenericType(elementType)
                                         .GetProperty(IndexPropertyName);
            MethodInfo addMethod = typeof(ICollection <>)
                                   .MakeGenericType(elementType)
                                   .GetMethod(nameof(ICollection <object> .Add));

            if (PrimitiveTypes.Contains(elementType))
            {
                return (iterator) =>
                       {
                           Expression getElementExpression = ExpressionFactory.Call(context.SourceEntity, indexProperty.GetMethod, iterator);
                           return ExpressionFactory.Call(context.TargetEntity, addMethod, getElementExpression);
                       }
            }
            ;
            else
            {
                return (iterator) =>
                       {
                           Expression getElementExpression = ExpressionFactory.Call(context.SourceEntity, indexProperty.GetMethod, iterator);
                           MethodInfo cloneMethod          = CloneMethod.MakeGenericMethod(elementType);
                           Expression clonedElement        = ExpressionFactory.Call(context.CloneFactory, cloneMethod, getElementExpression);
                           return ExpressionFactory.Call(context.TargetEntity, addMethod, clonedElement);
                       }
            };
        }
示例#8
0
        private void AddListExpressions <TEntity>(IExpressionBuilder expressionBuilder, CloneExpressionContext context)
        {
            PropertyInfo listCountProperty = context
                                             .SourceEntity
                                             .Type
                                             .GetProperty(nameof(List <TEntity> .Count));

            context.TargetEntity = expressionBuilder.CreateObject <TEntity>(
                nameof(CloneExpressionContext.TargetEntity),
                new[] { typeof(int) },
                new[] { ExpressionFactory.Call(context.SourceEntity, listCountProperty.GetMethod) });
            expressionBuilder.For(context.SourceEntity, CloneListElementDelegate(expressionBuilder, context));
        }
示例#9
0
 private void AddArrayExpressions <TEntity>(IExpressionBuilder expressionBuilder, CloneExpressionContext context)
 {
     context.TargetEntity = expressionBuilder.CreateObject <TEntity>(
         nameof(CloneExpressionContext.TargetEntity),
         new[] { typeof(int) },
         new[] { ExpressionFactory.Call(context.SourceEntity, ArrayLengthProperty.GetMethod) });
     expressionBuilder.For(context.SourceEntity, CloneArrayElementDelegate(context));
 }
示例#10
0
 private void AddCollectionExpressions <TEntity>(IExpressionBuilder expressionBuilder, CloneExpressionContext context)
 {
     if (typeof(Array).IsAssignableFrom(typeof(TEntity)))
     {
         AddArrayExpressions <TEntity>(expressionBuilder, context);
     }
     else
     {
         AddListExpressions <TEntity>(expressionBuilder, context);
     }
 }