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)); }
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); }
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))); }
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); }
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); }
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); }
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); }
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); }
private static ConcreteTypeCreator BuildCreator(Type targetType) { var creator = new ConcreteTypeCreator(new Lazy <Func <IDictionary <string, object>, object> >(() => BuildLambda(targetType), LazyThreadSafetyMode.PublicationOnly)); return(creator); }
private static ConcreteTypeCreator BuildCreator(Type targetType) { var creator = new ConcreteTypeCreator(new Lazy<Func<IDictionary<string, object>, object>>(() => BuildLambda(targetType), LazyThreadSafetyMode.PublicationOnly)); return creator; }