internal ComplexPropertyInterceptor(ChangeTrackingSettings changeTrackingSettings, Graph graph) { _ChangeTrackingSettings = changeTrackingSettings; _Graph = graph; _Trackables = new Dictionary <string, object>(); _TrackablesLock = new object(); }
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())); }