コード例 #1
0
        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();
            }
        }