コード例 #1
0
        private Expression BuildArrayCreator()
        {
            if (!_property.CanWrite)
            {
                return(null);
            }

            var genericType     = _property.PropertyType.GetGenericArguments().Single();
            var creatorInstance = ConcreteTypeCreator.Get(genericType);
            var collection      = Expression.Variable(_property.PropertyType);

            var createCollection = MakeCreateNewCollection(collection, genericType);

            if (createCollection == null)
            {
                return(null);
            }

            var addMethod = _property.PropertyType.GetMethod("Add");

            if (addMethod == null)
            {
                return(null);
            }

            return(BuildCollectionCreatorExpression(genericType, creatorInstance, collection, createCollection, addMethod));
        }
コード例 #2
0
        public bool TryCreate(IDictionary <string, object> data, out object result)
        {
            bool   anyPropertiesSet = false;
            object obj = Activator.CreateInstance(_concreteType);
            object value;

            foreach (var propertyInfo in _concreteType.GetProperties().Where(pi => CanSetProperty(pi, data)))
            {
                value = data[propertyInfo.Name];

                if (ConcreteCollectionTypeCreator.IsCollectionType(propertyInfo.PropertyType))
                {
                    if (!ConcreteCollectionTypeCreator.TryCreate(propertyInfo.PropertyType, (IEnumerable)value, out value))
                    {
                        continue;
                    }
                }
                else
                {
                    var subData = value as IDictionary <string, object>;
                    if (subData != null && !ConcreteTypeCreator.Get(propertyInfo.PropertyType).TryCreate(subData, out value))
                    {
                        continue;
                    }
                }

                propertyInfo.SetValue(obj, value, null);
                anyPropertiesSet = true;
            }

            result = anyPropertiesSet ? obj : null;

            return(anyPropertiesSet);
        }
コード例 #3
0
        private Expression BuildCollectionCreatorExpression(Type genericType, ConcreteTypeCreator creatorInstance, ParameterExpression collection, BinaryExpression createCollection, MethodInfo addMethod)
        {
            BlockExpression dictionaryBlock;
            var             isDictionaryCollection = BuildComplexTypeCollectionPopulator(collection, genericType, addMethod, createCollection, creatorInstance, out dictionaryBlock);

            BlockExpression objectBlock;
            var             isObjectcollection = BuildSimpleTypeCollectionPopulator(collection, genericType, addMethod, createCollection, creatorInstance, out objectBlock);

            return(Expression.IfThenElse(isDictionaryCollection, dictionaryBlock,
                                         Expression.IfThen(isObjectcollection, objectBlock)));
        }
コード例 #4
0
            protected bool TryConvertElement(Type type, object value, out object result)
            {
                result = null;
                if (value == null)
                {
                    return(true);
                }

                var valueType = value.GetType();

                if (type.IsAssignableFrom(valueType))
                {
                    result = value;
                    return(true);
                }

                try
                {
                    var code = Convert.GetTypeCode(value);

                    if (type.IsEnum)
                    {
                        return(ConvertEnum(type, value, out result));
                    }
                    if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable <>))
                    {
                        result = System.Convert.ChangeType(value, Nullable.GetUnderlyingType(type));
                        return(true);
                    }
                    if (code != TypeCode.Object)
                    {
                        result = System.Convert.ChangeType(value, type);
                        return(true);
                    }
                    var data = value as IDictionary <string, object>;
                    if (data != null)
                    {
                        return(ConcreteTypeCreator.Get(type).TryCreate(data, out result));
                    }
                }
                catch (FormatException)
                {
                    return(false);
                }
                catch (ArgumentException)
                {
                    return(false);
                }

                return(true);
            }
コード例 #5
0
        private object ConvertAndCacheReference(Type type, IDictionary <string, object> data)
        {
            _concreteObject = null;
            object result;

            if (ConcreteTypeCreator.Get(type).TryCreate(data, out result))
            {
                Interlocked.CompareExchange(ref _concreteObject, new WeakReference(result), null);
                return(_concreteObject.Target);
            }

            Interlocked.CompareExchange(ref _concreteObject, new WeakReference(CastFailureObject), null);
            return(null);
        }
コード例 #6
0
        private BinaryExpression CreateComplexAssign()
        {
            var creator = Expression.Constant(ConcreteTypeCreator.Get(_property.PropertyType));
            var methodCallExpression = Expression.Call(creator, CreatorCreateMethod,
// ReSharper disable PossiblyMistakenUseOfParamsMethod
                                                       Expression.Convert(_itemProperty,
                                                                          typeof(IDictionary <string, object>)));
// ReSharper restore PossiblyMistakenUseOfParamsMethod

            var complexAssign = Expression.Assign(_nameProperty,
                                                  Expression.Convert(
                                                      methodCallExpression, _property.PropertyType));

            return(complexAssign);
        }
コード例 #7
0
        private TypeBinaryExpression BuildSimpleTypeCollectionPopulator(ParameterExpression collection, Type genericType,
                                                                        MethodInfo addMethod, BinaryExpression createCollection,
                                                                        ConcreteTypeCreator creatorInstance, out BlockExpression block)
        {
            var creator = Expression.Constant(creatorInstance);
            var array   = Expression.Variable(typeof(object[]));
            var i       = Expression.Variable(typeof(int));
            var current = Expression.Variable(typeof(object));

            var isObjectCollection = Expression.TypeIs(_itemProperty,
                                                       typeof(IEnumerable <object>));

            var toArray = Expression.Assign(array,
                                            Expression.Call(ToArrayObjectMethod,
                                                            Expression.Convert(_itemProperty,
                                                                               typeof(IEnumerable <object>))));
            var start = Expression.Assign(i, Expression.Constant(0));
            var label = Expression.Label();
            var loop  = Expression.Loop(
                Expression.IfThenElse(
                    Expression.LessThan(i, Expression.Property(array, ArrayObjectLengthProperty)),
                    Expression.Block(
                        Expression.Assign(current, Expression.ArrayIndex(array, i)),
                        Expression.IfThenElse(
                            Expression.TypeIs(current, typeof(IDictionary <string, object>)),
                            Expression.Call(collection, addMethod,
                                            Expression.Convert(Expression.Call(creator, CreatorCreateMethod,
                                                                               Expression.Convert(current, typeof(IDictionary <string, object>))),
                                                               genericType)),
                            Expression.Call(collection, addMethod,
                                            Expression.Convert(current, genericType))),
                        Expression.PreIncrementAssign(i)
                        ),
                    Expression.Break(label)
                    ),
                label
                );

            block = Expression.Block(
                new[] { array, i, collection, current },
                createCollection,
                toArray,
                start,
                loop,
                _property.CanWrite ? (Expression)Expression.Assign(_nameProperty, collection) : Expression.Empty());

            return(isObjectCollection);
        }
コード例 #8
0
        private Expression BuildCollectionCreator()
        {
            var genericType     = _property.PropertyType.GetGenericArguments().Single();
            var creatorInstance = ConcreteTypeCreator.Get(genericType);
            var collection      = Expression.Variable(_property.PropertyType);
            BinaryExpression createCollection = null;

            if (_property.CanWrite)
            {
                createCollection = MakeCreateNewCollection(collection, genericType);
            }
            else
            {
                createCollection = Expression.Assign(collection, _nameProperty);
            }

            var addMethod = _property.PropertyType.GetInterfaceMethod("Add");

            if (createCollection != null && addMethod != null)
            {
                return(BuildCollectionCreatorExpression(genericType, creatorInstance, collection, createCollection, addMethod));
            }
            return(null);
        }
コード例 #9
0
        private static ConcreteTypeCreator BuildCreator(Type targetType)
        {
            var creator = new ConcreteTypeCreator(new Lazy <Func <IDictionary <string, object>, object> >(() => BuildLambda(targetType), LazyThreadSafetyMode.PublicationOnly));

            return(creator);
        }
コード例 #10
0
 private static ConcreteTypeCreator BuildCreator(Type targetType)
 {
     var creator = new ConcreteTypeCreator(new Lazy<Func<IDictionary<string, object>, object>>(() => BuildLambda(targetType), LazyThreadSafetyMode.PublicationOnly));
     return creator;
 }