Example #1
0
 internal ComplexPropertyInterceptor(ChangeTrackingSettings changeTrackingSettings, Graph graph)
 {
     _ChangeTrackingSettings = changeTrackingSettings;
     _Graph          = graph;
     _Trackables     = new Dictionary <string, object>();
     _TrackablesLock = new object();
 }
Example #2
0
 internal ChangeTrackingCollectionInterceptor(IList <T> target, ChangeTrackingSettings changeTrackingSettings, Graph graph)
 {
     _ChangeTrackingSettings = changeTrackingSettings;
     _Graph = graph;
     for (int i = 0; i < target.Count; i++)
     {
         target[i] = ChangeTrackingFactory.Default.AsTrackable(target[i], ChangeStatus.Unchanged, ItemCanceled, _ChangeTrackingSettings, _Graph);
     }
     _WrappedTarget = new ChangeTrackingBindingList <T>(target, DeleteItem, ItemCanceled, _ChangeTrackingSettings, _Graph);
     _DeletedItems  = new List <T>();
 }
        public ChangeTrackingBindingList(IList <T> list, Action <T> deleteItem, Action <T> itemCanceled, ChangeTrackingSettings changeTrackingSettings, Graph graph)
            : base(list)
        {
            _DeleteItem             = deleteItem;
            _ItemCanceled           = itemCanceled;
            _ChangeTrackingSettings = changeTrackingSettings;
            _Graph = graph;
            var bindingListType = typeof(ChangeTrackingBindingList <T>).BaseType;

            bindingListType.GetField("raiseItemChangedEvents", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic).SetValue(this, true);
            var hookMethod = bindingListType.GetMethod("HookPropertyChanged", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);

            foreach (var item in list)
            {
                hookMethod.Invoke(this, new object[] { item });
            }
        }
        internal object AsTrackableCollectionChild(Type type, object target, ChangeTrackingSettings changeTrackingSettings, Graph graph)
        {
            ThrowIfTargetIsProxy(target);
            ProxyWeakTargetMap existing = graph.GetExistingProxyForTarget(target);

            if (existing != null)
            {
                return(existing.Proxy);
            }
            Type   genericArgument = type.GetGenericArguments().First();
            object proxy           = _ProxyGenerator.CreateInterfaceProxyWithTarget(typeof(IList <>).MakeGenericType(genericArgument),
                                                                                    new[] { typeof(IChangeTrackableCollection <>).MakeGenericType(genericArgument), typeof(IRevertibleChangeTrackingInternal), typeof(IBindingList), typeof(ICancelAddNew), typeof(INotifyCollectionChanged) },
                                                                                    target,
                                                                                    GetOptions(genericArgument),
                                                                                    CreateInterceptor(typeof(ChangeTrackingCollectionInterceptor <>).MakeGenericType(genericArgument), target, changeTrackingSettings, graph));

            graph.Add(new ProxyWeakTargetMap(target, proxy));
            return(proxy);
        }
        internal ICollection <T> AsTrackableCollection <T>(ICollection <T> target, ChangeTrackingSettings changeTrackingSettings) where T : class
        {
            if (!(target is IList <T> list))
            {
                list = target.ToList();
            }
            ThrowIfTargetIsProxy(list);
            if (list.OfType <IChangeTrackable <T> >().Any(ct => ct.ChangeTrackingStatus != ChangeStatus.Unchanged))
            {
                throw new InvalidOperationException("some items in the collection are already being tracked");
            }

            Graph  graph = new Graph();
            object proxy = _ProxyGenerator.CreateInterfaceProxyWithTarget(typeof(IList <T>),
                                                                          new[] { typeof(IChangeTrackableCollection <T>), typeof(IRevertibleChangeTrackingInternal), typeof(IBindingList), typeof(ICancelAddNew), typeof(INotifyCollectionChanged) }, list, GetOptions(typeof(T)), new ChangeTrackingCollectionInterceptor <T>(list, changeTrackingSettings, graph));

            graph.Add(new ProxyWeakTargetMap(list, proxy));
            return((ICollection <T>)proxy);
        }
        internal T AsTrackable <T>(T target, ChangeStatus status, Action <T> notifyParentListItemCanceled, ChangeTrackingSettings changeTrackingSettings, Graph graph) where T : class
        {
            ThrowIfTargetIsProxy(target);
            ProxyWeakTargetMap existing = graph.GetExistingProxyForTarget(target);

            if (existing != null)
            {
                return((T)existing.Proxy);
            }

            //if T was ICollection<T> it would of gone to one of the other overloads
            if (target as ICollection != null)
            {
                throw new InvalidOperationException("Only IList<T>, List<T> and ICollection<T> are supported");
            }

            var    changeTrackingInterceptor        = new ChangeTrackingInterceptor <T>(status);
            var    notifyPropertyChangedInterceptor = new NotifyPropertyChangedInterceptor <T>(changeTrackingInterceptor);
            var    editableObjectInterceptor        = new EditableObjectInterceptor <T>(notifyParentListItemCanceled);
            var    complexPropertyInterceptor       = new ComplexPropertyInterceptor <T>(changeTrackingSettings, graph);
            var    collectionPropertyInterceptor    = new CollectionPropertyInterceptor <T>(changeTrackingSettings, graph);
            object proxy = _ProxyGenerator.CreateClassProxyWithTarget(typeof(T),
                                                                      new[] { typeof(IChangeTrackableInternal), typeof(IRevertibleChangeTrackingInternal), typeof(IChangeTrackable <T>), typeof(IChangeTrackingManager), typeof(IComplexPropertyTrackable), typeof(ICollectionPropertyTrackable), typeof(IEditableObjectInternal), typeof(INotifyPropertyChanged) },
                                                                      target,
                                                                      GetOptions(typeof(T)),
                                                                      notifyPropertyChangedInterceptor,
                                                                      changeTrackingInterceptor,
                                                                      editableObjectInterceptor,
                                                                      complexPropertyInterceptor,
                                                                      collectionPropertyInterceptor);

            CopyFieldsAndProperties(source: target, target: proxy);
            notifyPropertyChangedInterceptor.IsInitialized = true;
            changeTrackingInterceptor.IsInitialized        = true;
            editableObjectInterceptor.IsInitialized        = true;
            complexPropertyInterceptor.IsInitialized       = true;
            collectionPropertyInterceptor.IsInitialized    = true;
            graph.Add(new ProxyWeakTargetMap(target, proxy));
            return((T)proxy);
        }
        internal object AsTrackableChild(Type type, object target, Action <object> notifyParentItemCanceled, ChangeTrackingSettings changeTrackingSettings, Internal.Graph graph)
        {
            ThrowIfTargetIsProxy(target);
            ProxyWeakTargetMap existing = graph.GetExistingProxyForTarget(target);

            if (existing != null)
            {
                return(existing.Proxy);
            }
            IInterceptor changeTrackingInterceptor        = CreateInterceptor(typeof(ChangeTrackingInterceptor <>).MakeGenericType(type), ChangeStatus.Unchanged);
            IInterceptor notifyPropertyChangedInterceptor = CreateInterceptor(typeof(NotifyPropertyChangedInterceptor <>).MakeGenericType(type), changeTrackingInterceptor);
            IInterceptor editableObjectInterceptor        = CreateInterceptor(typeof(EditableObjectInterceptor <>).MakeGenericType(type), notifyParentItemCanceled);
            IInterceptor complexPropertyInterceptor       = CreateInterceptor(typeof(ComplexPropertyInterceptor <>).MakeGenericType(type), changeTrackingSettings, graph);
            IInterceptor collectionPropertyInterceptor    = CreateInterceptor(typeof(CollectionPropertyInterceptor <>).MakeGenericType(type), changeTrackingSettings, graph);
            object       proxy = _ProxyGenerator.CreateClassProxyWithTarget(type,
                                                                            new[] { typeof(IChangeTrackableInternal), typeof(IRevertibleChangeTrackingInternal), typeof(IChangeTrackable <>).MakeGenericType(type), typeof(IChangeTrackingManager), typeof(IComplexPropertyTrackable), typeof(ICollectionPropertyTrackable), typeof(IEditableObjectInternal), typeof(INotifyPropertyChanged) },
                                                                            target,
                                                                            GetOptions(type),
                                                                            notifyPropertyChangedInterceptor,
                                                                            changeTrackingInterceptor,
                                                                            editableObjectInterceptor,
                                                                            complexPropertyInterceptor,
                                                                            collectionPropertyInterceptor);

            CopyFieldsAndProperties(type: type, source: target, target: proxy);
            ((IInterceptorSettings)notifyPropertyChangedInterceptor).IsInitialized = true;
            ((IInterceptorSettings)changeTrackingInterceptor).IsInitialized        = true;
            ((IInterceptorSettings)editableObjectInterceptor).IsInitialized        = true;
            ((IInterceptorSettings)complexPropertyInterceptor).IsInitialized       = true;
            ((IInterceptorSettings)collectionPropertyInterceptor).IsInitialized    = true;
            graph.Add(new ProxyWeakTargetMap(target, proxy));
            return(proxy);
        }
 internal T AsTrackable <T>(T target, ChangeTrackingSettings changeTrackingSettings, ChangeStatus status = ChangeStatus.Unchanged) where T : class
 {
     return(AsTrackable(target, status, null, changeTrackingSettings, new Graph()));
 }