private static void ConditionallyRegisterDependentInstance(INotifyPropertyChanged target) { if (instanceTable.TryGetValue(target, out _)) { return; } lock (target) { if (instanceTable.TryGetValue(target, out _)) { return; } instanceTable.Add(target, null); } Type dependentType = target.GetType(); if (!dependencyDefinitions.TryGetValue(dependentType, out var dependenciesByPropertyName)) { return; } foreach (var dependency in dependenciesByPropertyName) { string targetPropertyName = dependency.Key; foreach (JsonPath jsonpath in dependency.Value) { var dependencyNodes = ImmutableQueue.Create(jsonpath.Root.Nodes.ToArray()); INotifyPropertyChanged source = target; source.ForwardPropertyChanged(dependencyNodes, target, targetPropertyName); } } }
private static Action ForwardPropertyChanged(this INotifyPropertyChanged source, ImmutableQueue <JsonPathNode> dependencyNodes, INotifyPropertyChanged target, string targetPropertyName) { WeakReference <INotifyPropertyChanged> wr = new WeakReference <INotifyPropertyChanged>(target); Action unsubscribe = null; dependencyNodes = dependencyNodes.Dequeue(out var node); switch (node) { case JsonPathPropertySelectorNode propertySelectorNode: string sourcePropertyName = propertySelectorNode.PropertyName; unsubscribe = source.ForwardPropertyChanged(sourcePropertyName, target, targetPropertyName); if (dependencyNodes.IsEmpty) { return(unsubscribe); } Action unsubscribeNested = null; if (propertySelectorNode.GetValue(source) is INotifyPropertyChanged nestedSource) { unsubscribeNested = nestedSource.ForwardPropertyChanged(dependencyNodes, target, targetPropertyName); unsubscribe += unsubscribeNested; } unsubscribe += source.Bind <INotifyPropertyChanged, object>(sourcePropertyName, (value) => { unsubscribe -= unsubscribeNested; unsubscribeNested?.Invoke(); if (!wr.TryGetTarget(out var t)) { return; } if (value is INotifyPropertyChanged nestedSrc) { unsubscribeNested = nestedSrc.ForwardPropertyChanged(dependencyNodes, t, targetPropertyName); unsubscribe += unsubscribeNested; } });