Exemplo n.º 1
0
        private IDisposable DeepSubscribeInternal(string path, Action handler, Lifetime rootLifetime = null)
        {
            rootLifetime = rootLifetime ?? new Lifetime();
            var observableRoot = DeepObservableRoot ?? this;
            IObservableObject currentObservable = observableRoot;
            var pathExpression = ObjectPathExpression.Parse(path);
            List <IObjectPathElement> currentPath = new List <IObjectPathElement>();

            var anyChangeLifetime = new Lifetime();

            for (int i = 0; i < pathExpression.Elements.Count; i++)
            {
                var propertyElement = pathExpression.Elements[i] as PropertyPathElement;
                if (propertyElement == null)
                {
                    throw new NotSupportedException("Indexers are not supported for deep observability");
                }

                currentPath.Add(propertyElement);

                ObjectPathExpression.TraceNode eval;

                if (i == pathExpression.Elements.Count - 1 && propertyElement.PropertyName == ObservableObject.AnyProperty)
                {
                    eval = new ObjectPathExpression.TraceNode()
                    {
                        Value = null
                    };
                }
                else
                {
                    eval = new ObjectPathExpression(currentPath).EvaluateAndTraceInfo(observableRoot).Last();
                    if (i != pathExpression.Elements.Count - 1 && (eval.MemberInfo as PropertyInfo).PropertyType.GetInterfaces().Contains(typeof(IObservableObject)) == false)
                    {
                        throw new NotSupportedException($"element {eval.MemberInfo.Name} is not observable");
                    }
                }

                currentObservable.SubscribeForLifetime(propertyElement.PropertyName, () =>
                {
                    handler();
                    if (anyChangeLifetime.IsExpired == false)
                    {
                        anyChangeLifetime.Dispose();
                    }

                    if (rootLifetime.IsExpired == false)
                    {
                        DeepSubscribeInternal(path, handler, rootLifetime);
                    }
                }, EarliestOf(anyChangeLifetime, rootLifetime));

                currentObservable = eval.Value as IObservableObject;

                if (currentObservable == null)
                {
                    break;
                }
            }

            return(rootLifetime);
        }