Esempio n. 1
0
        public IObjectGraphTrackingInfo GetTrackingGraphFromProperty(PropertyInfo property)
        {
            DeclaredObjectPropertyChangeTracking propertyTracking = null;

            PropertyTrackings.TryGetValue(property.GetBaseProperty(), out propertyTracking);

            List <IDeclaredObjectPropertyChangeTracking> hierarchy = new List <IDeclaredObjectPropertyChangeTracking>();

            bool searchTracking = true;

            while (searchTracking)
            {
                hierarchy.Add(propertyTracking);

                var result = PropertyTrackings.SingleOrDefault
                             (
                    t => t.Value.CurrentValue == propertyTracking.TargetObject &&
                    t.Value.Property.PropertyType.GetProperty(propertyTracking.Property.Name) == propertyTracking.Property.GetBaseProperty()
                             );

                if (result.Value != null)
                {
                    propertyTracking = result.Value;
                    property         = propertyTracking.Property;
                }
                else
                {
                    searchTracking = false;
                }
            }

            Contract.Assert(() => propertyTracking != null);

            return(new ObjectGraphTrackingInfo
                   (
                       propertyTracking.TargetObject,
                       hierarchy.Reverse <IDeclaredObjectPropertyChangeTracking>().ToImmutableList()
                   ));
        }
Esempio n. 2
0
        /// <summary>
        /// Adds or updates a tracked property state.
        /// </summary>
        /// <param name="property">The tracked property</param>
        /// <param name="targetObject">The object owning the tracked property</param>
        public void AddOrUpdateTracking(PropertyInfo property, object targetObject = null)
        {
            Contract.Requires(property != null, "Since this is tracking a property, the property itself cannot be null");
            Contract.Requires(targetObject == null || property.DeclaringType.IsAssignableFrom(targetObject.GetType()), "Given property must be declared on the given target object");

            lock (_syncLock)
            {
                targetObject = targetObject ?? TargetObject;

                object currentValue = targetObject.GetType().GetProperty(property.Name, DefaultBindingFlags)
                                      .GetValue(targetObject);

                DeclaredObjectPropertyChangeTracking existingTracking = null;

                Contract.Assert(PropertyTrackings != null, "Cannot add or update a tracking if tracking collection is null");

                PropertyInfo baseProperty = property.GetBaseProperty();

                DeclaredObjectPropertyChangeTracking tracking = null;

                if (Configuration.CanTrackProperty(property) && !PropertyTrackings.TryGetValue(baseProperty, out existingTracking))
                {
                    DeclaredObjectPropertyChangeTracking declaredTracking = new DeclaredObjectPropertyChangeTracking(Configuration, TrackableObjectFactory, this, targetObject, baseProperty, property, currentValue);
                    tracking = declaredTracking;

                    PropertyTrackings.Add(baseProperty, declaredTracking);
                }
                else if (existingTracking != null)
                {
                    existingTracking.CurrentValue = currentValue;
                    tracking = existingTracking;
                }

                if (tracking != null && tracking.HasChanged)
                {
                    _Changed?.Invoke(this, new DeclaredObjectPropertyChangeEventArgs(targetObject, tracking));
                }
            }
        }