Example #1
0
        public void Intercept(IInvocation invocation)
        {
            Contract.Requires(() => invocation != null);

            IHasParent withParent = invocation.Proxy as IHasParent;

            if (withParent != null && invocation.Method.IsPublic && !invocation.Method.IsPropertyGetterOrSetter())
            {
                InterceptMethod(invocation, withParent);
            }
            else
            {
                InterceptMethod(invocation);
            }
        }
        /// <summary>
        /// Gets current tracked object change tracker.
        /// </summary>
        /// <param name="some">The change-tracked object</param>
        /// <returns>The change tracker</returns>
        public static IObjectChangeTracker GetChangeTracker(this object some)
        {
            Contract.Requires(() => some != null, "Reference must not be null to get object change tracker");

            IChangeTrackableObject trackableObject = some as IChangeTrackableObject;

            if (trackableObject == null)
            {
                IHasParent withParent = some as IHasParent;

                if (withParent != null)
                {
                    trackableObject = withParent.ParentObject;
                }
            }

            Contract.Assert(() => trackableObject != null, "An object must be trackable in order to get its change tracker");

            return(trackableObject.GetChangeTrackingContext().ChangeTracker);
        }
Example #3
0
 public void AddChild(IHasParent Child)
 {
     Children.Add(Child);
     Child.Parent = this;
 }
        protected override void InterceptMethod(IInvocation invocation, IHasParent withParent)
        {
            Type collectionType = invocation.Method.DeclaringType;

            if (collectionType.IsEnumerable() && invocation.Arguments.Length == 1)
            {
                IChangeTrackableCollection trackableCollection = (IChangeTrackableCollection)withParent;
                IChangeTrackableObject     changedItem         =
                    invocation.Arguments[0] as IChangeTrackableObject
                    ?? TrackableObjectFactory.CreateFrom(invocation.Arguments[0]) as IChangeTrackableObject;

                IEnumerable <object> currentItems;
                Type collectionItemType   = withParent.GetCollectionItemType();
                bool itemsAreKeyValuePair = collectionItemType.GetTypeInfo().IsGenericType&& collectionItemType == typeof(KeyValuePair <,>).MakeGenericType(collectionItemType.GenericTypeArguments);

                if (itemsAreKeyValuePair)
                {
                    currentItems = ((IEnumerable)withParent).Cast <object>();
                }
                else
                {
                    currentItems = ((IEnumerable <object>)withParent).ToList();
                }

                invocation.Arguments[0] = changedItem ?? invocation.Arguments[0];
                invocation.Proceed();

                KeyValuePair <Type, CollectionImplementation> implementation =
                    Configuration.Collections.GetImplementation(collectionType);

                CollectionChangeContext changeContext = new CollectionChangeContext
                                                        (
                    !itemsAreKeyValuePair ? (IEnumerable <object>)trackableCollection : Enumerable.Empty <object>(),
                    currentItems,
                    trackableCollection.ParentObjectProperty,
                    trackableCollection.AddedItems,
                    trackableCollection.RemovedItems
                                                        );

                if (!itemsAreKeyValuePair)
                {
                    Activator.CreateInstance(implementation.Value.ChangeInterceptor.MakeGenericType(trackableCollection.GetCollectionItemType()), changeContext)
                    .CallMethod(invocation.Method.Name, invocation.Arguments);
                }

                switch (changeContext.Change)
                {
                case CollectionChange.Add:
                    trackableCollection.RaiseCollectionChanged(NotifyCollectionChangedAction.Add, new[] { changedItem });
                    break;

                case CollectionChange.Remove:
                    trackableCollection.RaiseCollectionChanged(NotifyCollectionChangedAction.Remove, new[] { changedItem });
                    break;
                }
            }
            else
            {
                invocation.Proceed();
            }
        }
 protected virtual void InterceptMethod(IInvocation invocation, IHasParent withParent)
 {
 }