Exemplo n.º 1
0
        public virtual void SetValue(object targetResource, string propertyName, object propertyValue)
        {
            ExceptionUtilities.CheckArgumentNotNull(targetResource, "targetResource");
            ExceptionUtilities.CheckArgumentNotNull(propertyName, "propertyName");
            UpdatableToken token = UpdatableToken.AssertIsToken(targetResource, "targetResource");

            targetResource = token.Resource;
            token.PendingPropertyUpdates[propertyName] = propertyValue;
            this.pendingChanges.Add(delegate {
                object generatedValue;
                Type t          = targetResource.GetType();
                PropertyInfo pi = t.GetProperty(propertyName);
                ExceptionUtilities.CheckObjectNotNull(pi, "Unable to find property '{0}' on type '{1}'", new object[] { propertyName, targetResource.GetType().Name });
                if (this.TryGetStoreGeneratedValue(GetResourceTypeFullName(t), propertyName, out generatedValue))
                {
                    propertyValue = generatedValue;
                }
                if (this.IsCollectionProperty(pi))
                {
                    ExceptionUtilities.CheckObjectNotNull(propertyValue, "Collection property value was null", new object[0]);
                    IEnumerable enumerable = propertyValue as IEnumerable;
                    ExceptionUtilities.CheckObjectNotNull(enumerable, "Collection property value was not an enumerable", new object[0]);
                    this.SetCollectionPropertyValue(targetResource, pi, enumerable);
                }
                else
                {
                    propertyValue = UpdatableToken.ResolveIfToken(propertyValue);
                    pi.SetValue(targetResource, propertyValue, null);
                }
            });
        }
Exemplo n.º 2
0
        protected virtual void SetCollectionPropertyValue(object targetResource, PropertyInfo propertyInfo, IEnumerable propertyValue)
        {
            object collection;

            ExceptionUtilities.CheckArgumentNotNull(targetResource, "targetResource");
            ExceptionUtilities.CheckArgumentNotNull(propertyInfo, "propertyInfo");
            ExceptionUtilities.CheckArgumentNotNull(propertyValue, "propertyValue");
            Type collectionType = this.GetCollectionPropertyType(GetResourceTypeFullName(propertyInfo.ReflectedType), propertyInfo.Name);

            ExceptionUtilities.CheckObjectNotNull(collectionType, "Could not infer collection type for property", new object[0]);
            propertyValue = propertyValue.Cast <object>().Select <object, object>(delegate(object o) {
                return(UpdatableToken.ResolveIfToken(o));
            });
            ConstructorInfo enumerableConstructor = collectionType.GetConstructor(new Type[] { typeof(IEnumerable) });

            if (enumerableConstructor != null)
            {
                collection = enumerableConstructor.Invoke(new object[] { propertyValue });
            }
            else if (collectionType.IsGenericType && (collectionType.GetGenericArguments().Count <Type>() == 1))
            {
                Type            typeArgument = collectionType.GetGenericArguments().Single <Type>();
                ConstructorInfo typedEnumerableConstructor = collectionType.GetConstructor(new Type[] { typeof(IEnumerable <>).MakeGenericType(new Type[] { typeArgument }) });
                if (typedEnumerableConstructor != null)
                {
                    object typedEnumerable = typeof(Enumerable).GetMethod("Cast").MakeGenericMethod(new Type[] { typeArgument }).Invoke(null, new object[] { propertyValue });
                    collection = typedEnumerableConstructor.Invoke(new object[] { typedEnumerable });
                }
                else
                {
                    MethodInfo typedAddMethod = collectionType.GetMethod("Add", new Type[] { typeArgument });
                    ExceptionUtilities.CheckObjectNotNull(typedAddMethod, "Could not find constructor or add method for type: " + collectionType.FullName, new object[0]);
                    collection = Activator.CreateInstance(collectionType);
                    foreach (object element in propertyValue)
                    {
                        typedAddMethod.Invoke(collection, new object[] { element });
                    }
                }
            }
            else
            {
                MethodInfo addMethod = collectionType.GetMethod("Add");
                ExceptionUtilities.CheckObjectNotNull(addMethod, "Could not find constructor or add method for type: " + collectionType.FullName, new object[0]);
                collection = Activator.CreateInstance(collectionType);
                foreach (object element in propertyValue)
                {
                    addMethod.Invoke(collection, new object[] { element });
                }
            }
            propertyInfo.SetValue(targetResource, collection, null);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Sets the value of the given property on the target object
        /// </summary>
        /// <param name="targetResource">target object which defines the property</param>
        /// <param name="propertyName">name of the property whose value needs to be updated</param>
        /// <param name="propertyValue">value of the property</param>
        public virtual void SetValue(object targetResource, string propertyName, object propertyValue)
        {
            ExceptionUtilities.CheckArgumentNotNull(targetResource, "targetResource");
            ExceptionUtilities.CheckArgumentNotNull(propertyName, "propertyName");

            var token = UpdatableToken.AssertIsToken(targetResource, "targetResource");

            targetResource = token.Resource;

            // note that propertyValue might be a token itself, but GetValue will simply return whatever is stored in the token
            token.PendingPropertyUpdates[propertyName] = propertyValue;

            // Add a pending change to modify the value of the property
            this.pendingChanges.Add(() =>
            {
                Type t          = targetResource.GetType();
                PropertyInfo pi = t.GetProperty(propertyName);
                ExceptionUtilities.CheckObjectNotNull(pi, "Unable to find property '{0}' on type '{1}'", propertyName, targetResource.GetType().Name);

                string entitySetName = this.ReflectionMetadataHelper.FindSetNameForType(t);
                object generatedValue;
                if (this.TryGetStoreGeneratedValue(entitySetName, GetResourceTypeFullName(t), propertyName, out generatedValue))
                {
                    propertyValue = generatedValue;
                }

                if (this.IsCollectionProperty(pi))
                {
                    ExceptionUtilities.CheckObjectNotNull(propertyValue, "Collection property value was null");

                    var enumerable = propertyValue as IEnumerable;
                    ExceptionUtilities.CheckObjectNotNull(enumerable, "Collection property value was not an enumerable");

                    this.SetCollectionPropertyValue(targetResource, pi, enumerable);
                }
                else
                {
                    propertyValue = UpdatableToken.ResolveIfToken(propertyValue);
                    pi.SetValue(targetResource, propertyValue, null);
                }
            });
        }
Exemplo n.º 4
0
        /// <summary>
        /// Sets the value of a collection property
        /// </summary>
        /// <param name="targetResource">The resource to set the value on</param>
        /// <param name="propertyInfo">The property to set</param>
        /// <param name="propertyValue">The collection value</param>
        protected virtual void SetCollectionPropertyValue(object targetResource, PropertyInfo propertyInfo, IEnumerable propertyValue)
        {
            ExceptionUtilities.CheckArgumentNotNull(targetResource, "targetResource");
            ExceptionUtilities.CheckArgumentNotNull(propertyInfo, "propertyInfo");
            ExceptionUtilities.CheckArgumentNotNull(propertyValue, "propertyValue");

            Type collectionType = this.GetCollectionPropertyType(GetResourceTypeFullName(propertyInfo.ReflectedType), propertyInfo.Name);

            ExceptionUtilities.CheckObjectNotNull(collectionType, "Could not infer collection type for property");
            object collection;

            // need to go through the enumerable and resolve any tokens
            propertyValue = propertyValue.Cast <object>().Select(o => UpdatableToken.ResolveIfToken(o));

            // Algorithm for setting a collection value:
            // - Get a collection of the correct instance type
            //   - Look for a constructor that takes a non-generic IEnumerable, if one is found invoke it
            //   - If the type is generic
            //     - look for a constuctor taking IEnumerable<T>, if one is found invoke it
            //     - look for an Add method taking T, if one is found use default constructor and add each item
            //   - look for an untyped Add method, if one is found use default constructor and add each item
            // - Set the property normally, using the new collection instance
            var enumerableConstructor = collectionType.GetConstructor(new Type[] { typeof(IEnumerable) });

            if (enumerableConstructor != null)
            {
                // invoke the IEnumerable constructor with the property value
                collection = enumerableConstructor.Invoke(new object[] { propertyValue });
            }
            else if (collectionType.IsGenericType && collectionType.GetGenericArguments().Count() == 1)
            {
                // determine the element type
                var typeArgument = collectionType.GetGenericArguments().Single();

                // look for a constructor taking IEnumerable<T>
                var typedEnumerableConstructor = collectionType.GetConstructor(new Type[] { typeof(IEnumerable <>).MakeGenericType(typeArgument) });

                if (typedEnumerableConstructor != null)
                {
                    // convert the IEnumerable into IEnumerable<T> using Enumerable.Cast
                    var typedEnumerable = typeof(Enumerable).GetMethod("Cast").MakeGenericMethod(typeArgument).Invoke(null, new object[] { propertyValue });

                    // invoke the constructor
                    collection = typedEnumerableConstructor.Invoke(new object[] { typedEnumerable });
                }
                else
                {
                    // look for an Add method accepting T
                    var typedAddMethod = collectionType.GetMethod("Add", new Type[] { typeArgument });

                    // for generic types, we must find either a constructor or an Add method
                    ExceptionUtilities.CheckObjectNotNull(typedAddMethod, "Could not find constructor or add method for type: " + collectionType.FullName);

                    // create a new instance, and add each item
                    collection = Activator.CreateInstance(collectionType);
                    foreach (var element in propertyValue)
                    {
                        typedAddMethod.Invoke(collection, new object[] { element });
                    }
                }
            }
            else
            {
                // look for an Add method
                var addMethod = collectionType.GetMethod("Add");

                // fail if no method is found
                ExceptionUtilities.CheckObjectNotNull(addMethod, "Could not find constructor or add method for type: " + collectionType.FullName);

                // create a new instance and add each item
                collection = Activator.CreateInstance(collectionType);
                foreach (var element in propertyValue)
                {
                    addMethod.Invoke(collection, new object[] { element });
                }
            }

            // set the new collection instance as the value
            propertyInfo.SetValue(targetResource, collection, null);
        }