示例#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);
                }
            });
        }
示例#2
0
        /// <summary>
        /// Resets the value of the given resource to its default value
        /// </summary>
        /// <param name="resource">resource whose value needs to be reset</param>
        /// <returns>same resource with its value reset</returns>
        public virtual object ResetResource(object resource)
        {
            ExceptionUtilities.CheckArgumentNotNull(resource, "resource");
            var token = UpdatableToken.AssertIsToken(resource, "resource");

            resource = token.Resource;

            // create a new token to return
            token = new UpdatableToken(resource);

            object newInstance = Activator.CreateInstance(resource.GetType());

            ExceptionUtilities.CheckObjectNotNull(newInstance, "Cannot reset resource because unable to creating new instance of type '{0}' returns null", resource.GetType().Name);

            string[] propertiesToReset = this.ReflectionMetadataHelper.GetPropertiesToReset(GetResourceTypeFullName(resource.GetType()));

            // We must only reset values of scalar, scalar Collection, complex, and complexCollection properties, the key and navigations must stay the same
            foreach (string propertyToReset in propertiesToReset)
            {
                PropertyInfo pi = newInstance.GetType().GetProperty(propertyToReset);
                ExceptionUtilities.CheckObjectNotNull(pi, "Cannot reset resource because unable to find property '{0}'", propertyToReset);
                object newValue = pi.GetValue(newInstance, null);
                this.pendingChanges.Add(() => pi.SetValue(resource, newValue, null));
                token.PendingPropertyUpdates[propertyToReset] = newValue;
            }

            return(token);
        }
示例#3
0
        /// <summary>
        /// Gets 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>
        /// <returns>the value of the property for the given target resource</returns>
        public virtual object GetValue(object targetResource, string propertyName)
        {
            ExceptionUtilities.CheckArgumentNotNull(targetResource, "targetResource");
            ExceptionUtilities.CheckArgumentNotNull(propertyName, "propertyName");

            // resolve the token, and return a pending value if there is one
            // NOTE: this code is specifically to handle cases of mapped complex-type values, because the product does not cache the
            // value returned by CreateResource so we need to take into account any pending updates, or we risk returning stale data
            var token = UpdatableToken.AssertIsToken(targetResource, "targetResource");

            if (token.PendingPropertyUpdates.ContainsKey(propertyName))
            {
                return(token.PendingPropertyUpdates[propertyName]);
            }

            targetResource = token.Resource;
            PropertyInfo pi = targetResource.GetType().GetProperty(propertyName);

            ExceptionUtilities.CheckObjectNotNull(pi, "Cannot find the property '{0}' on type '{1}'", propertyName, targetResource.GetType().Name);

            var value = pi.GetValue(targetResource, null);

            // NOTE: we need to token-ize any complex values before returning them
            // we should have a better way of telling a type is complex, but this works for now
            if (value != null && pi.PropertyType.Assembly == this.GetType().Assembly)
            {
                ExceptionUtilities.Assert(!this.ReflectionMetadataHelper.IsTypeAnEntityType(pi.PropertyType), "GetValue should never be called for reference properties. Type was '{0}', property was '{1}'", pi.PropertyType.FullName, propertyName);
                value = new UpdatableToken(value);
            }

            return(value);
        }
示例#4
0
        /// <summary>
        /// Adds the given value to the collection
        /// </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="resourceToBeAdded">value of the property which needs to be added</param>
        public virtual void AddReferenceToCollection(object targetResource, string propertyName, object resourceToBeAdded)
        {
            ExceptionUtilities.CheckArgumentNotNull(targetResource, "targetResource");
            ExceptionUtilities.CheckArgumentNotNull(propertyName, "propertyName");
            ExceptionUtilities.CheckArgumentNotNull(resourceToBeAdded, "resourceToBeAdded");

            // resolve the target token
            var targetToken = UpdatableToken.AssertIsToken(targetResource, "targetResource");

            targetResource = targetToken.Resource;

            // resolve the added token
            resourceToBeAdded = UpdatableToken.AssertIsTokenAndResolve(resourceToBeAdded, "resourceToBeAdded");

            // All resource set reference properties must be of type IList<T> where T is the type of an entitySet
            // Note that we don't support bi-directional relationships so we only handle the one resource set reference property in isolation.
            IList list = this.GetValue(targetToken, propertyName) as IList;

            ExceptionUtilities.CheckObjectNotNull(list, "Property '{0}' on type '{1}' was not a list", propertyName, targetResource.GetType().Name);

            this.pendingChanges.Add(() =>
            {
                list.Add(resourceToBeAdded);
            });
        }
示例#5
0
 public virtual void SetReference(object targetResource, string propertyName, object propertyValue)
 {
     ExceptionUtilities.CheckArgumentNotNull(targetResource, "targetResource");
     ExceptionUtilities.CheckArgumentNotNull(propertyName, "propertyName");
     if (propertyValue != null)
     {
         UpdatableToken.AssertIsToken(propertyValue, "propertyValue");
     }
     this.SetValue(targetResource, propertyName, propertyValue);
 }
示例#6
0
        public virtual void RemoveReferenceFromCollection(object targetResource, string propertyName, object resourceToBeRemoved)
        {
            ExceptionUtilities.CheckArgumentNotNull(targetResource, "targetResource");
            ExceptionUtilities.CheckArgumentNotNull(propertyName, "propertyName");
            ExceptionUtilities.CheckArgumentNotNull(resourceToBeRemoved, "resourceToBeRemoved");
            UpdatableToken.AssertIsToken(targetResource, "targetResource");
            resourceToBeRemoved = UpdatableToken.AssertIsTokenAndResolve(resourceToBeRemoved, "resourceToBeRemoved");
            IList list = this.GetValue(targetResource, propertyName) as IList;

            ExceptionUtilities.CheckObjectNotNull(list, "Property '{0}' on type '{1}' was not a list", new object[] { propertyName, targetResource.GetType().Name });
            this.pendingChanges.Add(delegate {
                list.Remove(resourceToBeRemoved);
            });
        }
示例#7
0
        /// <summary>
        /// Sets the value of the given reference 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 SetReference(object targetResource, string propertyName, object propertyValue)
        {
            ExceptionUtilities.CheckArgumentNotNull(targetResource, "targetResource");
            ExceptionUtilities.CheckArgumentNotNull(propertyName, "propertyName");
            if (propertyValue != null)
            {
                UpdatableToken.AssertIsToken(propertyValue, "propertyValue");
            }

            // Note that we don't support bi-directional relationships so we only handle the one resource reference property in isolation.

            // Our reference properties are just like normal properties we just set the property value to the new value
            //   we don't perform any special actions for references.
            // So just call the SetValue which will do exactly that.
            this.SetValue(targetResource, propertyName, propertyValue);
        }
示例#8
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);
                }
            });
        }
示例#9
0
        public virtual object ResetResource(object resource)
        {
            ExceptionUtilities.CheckArgumentNotNull(resource, "resource");
            UpdatableToken token = UpdatableToken.AssertIsToken(resource, "resource");

            resource = token.Resource;
            token    = new UpdatableToken(resource);
            object newInstance = Activator.CreateInstance(resource.GetType());

            ExceptionUtilities.CheckObjectNotNull(newInstance, "Cannot reset resource because unable to creating new instance of type '{0}' returns null", new object[] { resource.GetType().Name });
            foreach (string propertyToReset in this.MetadataHelper.GetPropertiesToReset(GetResourceTypeFullName(resource.GetType())))
            {
                PropertyInfo pi = newInstance.GetType().GetProperty(propertyToReset);
                ExceptionUtilities.CheckObjectNotNull(pi, "Cannot reset resource because unable to find property '{0}'", new object[] { propertyToReset });
                object newValue = pi.GetValue(newInstance, null);
                this.pendingChanges.Add(delegate {
                    pi.SetValue(resource, newValue, null);
                });
                token.PendingPropertyUpdates[propertyToReset] = newValue;
            }
            return(token);
        }
示例#10
0
        public virtual object GetValue(object targetResource, string propertyName)
        {
            ExceptionUtilities.CheckArgumentNotNull(targetResource, "targetResource");
            ExceptionUtilities.CheckArgumentNotNull(propertyName, "propertyName");
            UpdatableToken token = UpdatableToken.AssertIsToken(targetResource, "targetResource");

            if (token.PendingPropertyUpdates.ContainsKey(propertyName))
            {
                return(token.PendingPropertyUpdates[propertyName]);
            }
            targetResource = token.Resource;
            PropertyInfo pi = targetResource.GetType().GetProperty(propertyName);

            ExceptionUtilities.CheckObjectNotNull(pi, "Cannot find the property '{0}' on type '{1}'", new object[] { propertyName, targetResource.GetType().Name });
            object value = pi.GetValue(targetResource, null);

            if ((value != null) && (pi.PropertyType.Assembly == base.GetType().Assembly))
            {
                ExceptionUtilities.Assert(!this.MetadataHelper.IsTypeAnEntityType(pi.PropertyType), "GetValue should never be called for reference properties. Type was '{0}', property was '{1}'", new object[] { pi.PropertyType.FullName, propertyName });
                value = new UpdatableToken(value);
            }
            return(value);
        }