Beispiel #1
0
        public DependsOnMethod <T> OnChanged <TResult>(Expression <Func <T, TResult> > propertyAccessor)
        {
            PropertyAccessTree propertyAccessTree = ExpressionPropertyAnalyzer.Analyze(propertyAccessor);

            if (propertyAccessTree.DoesEntireTreeSupportINotifyPropertyChanging)
            {
                if (_propertyChangeSubscribers == null)
                {
                    _propertyChangeSubscribers = new List <IPropertyAccessTreeSubscriber <DependsOnMethod <T> > >();
                }

                var subscriber = propertyAccessTree.CreateCallbackSubscription <DependsOnMethod <T> >(OnAnyPropertyInSubscriptionChanges);

                _propertyChangeSubscribers.Add(subscriber);
            }
            else
            {
                if (_accessTreesWithoutNotifyPropertyChanging == null)
                {
                    _accessTreesWithoutNotifyPropertyChanging = new List <PropertyAccessTree>();
                }
                _accessTreesWithoutNotifyPropertyChanging.Add(propertyAccessTree);
            }

            return(this);
        }
        public void Analyze_ExpressionIncludesConstantImplementingINotifyPropertyChanged_TreeContainsTwoBranches()
        {
            Person localPersonAppearingAsConstantInExpression = new Person();
            Expression <Func <Person, int> > expression       = p => p.Age + localPersonAppearingAsConstantInExpression.Age;

            PropertyAccessTree tree = ExpressionPropertyAnalyzer.Analyze(expression);

            Assert.AreEqual(2, tree.Children.Count);
            PropertyAccessTreeNode parameterNode = tree.Children[0];

            Assert.IsInstanceOfType(typeof(ParameterNode), parameterNode);
            Assert.AreEqual(1, parameterNode.Children.Count);

            PropertyAccessNode parameterAgeNode = (PropertyAccessNode)parameterNode.Children[0];

            Assert.AreEqual(_ageProperty, parameterAgeNode.Property);
            Assert.AreEqual(0, parameterAgeNode.Children.Count);

            PropertyAccessTreeNode constantNode = tree.Children[1];

            Assert.IsInstanceOfType(typeof(ConstantNode), constantNode);
            Assert.AreEqual(localPersonAppearingAsConstantInExpression, ((ConstantNode)constantNode).Value);
            Assert.AreEqual(1, constantNode.Children.Count);

            PropertyAccessNode constantAgeNode = (PropertyAccessNode)constantNode.Children[0];

            Assert.AreEqual(_ageProperty, constantAgeNode.Property);
            Assert.AreEqual(0, constantAgeNode.Children.Count);
        }
        public void Analyze_ExpressionHasMultipleParametersWithReduntantAccessors_ReturnsMinimalPropertyAccessTree()
        {
            Expression <Func <Person, SimpleNotifyValue, int> > ageAdder = (person, simpleNotify) => person.Age + person.Age + simpleNotify.Value + simpleNotify.Value;

            var tree = ExpressionPropertyAnalyzer.Analyze(ageAdder);

            Assert.AreEqual(2, tree.Children.Count);

            ParameterNode personParameterNode = (ParameterNode)tree.Children[0];

            Assert.AreEqual(1, personParameterNode.Children.Count);
            Assert.AreEqual("person", personParameterNode.Name);
            PropertyAccessNode personAgePropertyAccessNode = (PropertyAccessNode)personParameterNode.Children[0];

            Assert.AreEqual(typeof(Person), personAgePropertyAccessNode.Property.DeclaringType);
            Assert.AreEqual("Age", personAgePropertyAccessNode.PropertyName);

            ParameterNode simpleNotifyParameterNode = (ParameterNode)tree.Children[1];

            Assert.AreEqual(1, simpleNotifyParameterNode.Children.Count);
            Assert.AreEqual("simpleNotify", simpleNotifyParameterNode.Name);
            PropertyAccessNode simpleNotifyValuePropertyAccessNode = (PropertyAccessNode)simpleNotifyParameterNode.Children[0];

            Assert.AreEqual(typeof(SimpleNotifyValue), simpleNotifyValuePropertyAccessNode.Property.DeclaringType);
            Assert.AreEqual("Value", simpleNotifyValuePropertyAccessNode.PropertyName);
        }
        public void Analyze_ExpressionContainsNewOperatorWithMemberAssignmentInitialization_ReturnsPropertyAccessTree()
        {
            Expression <Func <Person, Person> > expression = person => new Person()
            {
                Name = person.Name, Age = person.Age
            };

            var tree = ExpressionPropertyAnalyzer.Analyze(expression);

            Assert.AreEqual(1, tree.Children.Count);
            PropertyAccessTreeNode parameterNode = tree.Children[0];

            Assert.IsInstanceOfType(typeof(ParameterNode), parameterNode);
            Assert.AreEqual(2, parameterNode.Children.Count);

            PropertyAccessNode ageNode = (PropertyAccessNode)parameterNode.Children[0];

            Assert.AreEqual(_ageProperty, ageNode.Property);
            Assert.AreEqual(0, ageNode.Children.Count);

            PropertyAccessNode nameNode = (PropertyAccessNode)parameterNode.Children[1];

            Assert.AreEqual(_nameProperty, nameNode.Property);
            Assert.AreEqual(0, nameNode.Children.Count);
        }
        public void Analyze_ConditionalExpressionBothOneLevelAndTwoLevelProperties_TreeCorrect()
        {
            Expression <Func <Person, int> > expression = p => p.Age > 3 ? p.Age : p.Brother.Age;

            PropertyAccessTree tree = ExpressionPropertyAnalyzer.Analyze(expression);

            Assert.AreEqual(1, tree.Children.Count);
            PropertyAccessTreeNode parameterNode = tree.Children[0];

            Assert.AreEqual(2, parameterNode.Children.Count);

            PropertyAccessNode firstLevelAgeNode = (PropertyAccessNode)parameterNode.Children[1];

            Assert.AreEqual(_ageProperty, firstLevelAgeNode.Property);
            Assert.AreEqual(0, firstLevelAgeNode.Children.Count);

            PropertyAccessNode brotherNode = (PropertyAccessNode)parameterNode.Children[0];

            Assert.AreEqual(_brotherProperty, brotherNode.Property);
            Assert.AreEqual(1, brotherNode.Children.Count);

            PropertyAccessNode secondLevelAgeNode = (PropertyAccessNode)brotherNode.Children[0];

            Assert.AreEqual(_ageProperty, secondLevelAgeNode.Property);
            Assert.AreEqual(0, secondLevelAgeNode.Children.Count);
        }
        public void Analyze_ExpressionContainsNothingWithINotifyPropertyChanged_ReturnsNull()
        {
            Expression <Func <int, bool> > expression = i => i == 0;

            PropertyAccessTree tree = ExpressionPropertyAnalyzer.Analyze(expression);

            Assert.IsNull(tree);
        }
        public void Analyze_SpecialTypeFilterWithExpressionThatFailsFilter_ReturnsPropertyAccessTree()
        {
            Expression <Func <string, bool> > expression = str => str.Length == 0;

            PropertyAccessTree tree = ExpressionPropertyAnalyzer.Analyze(expression, type => type == typeof(int));

            Assert.IsNull(tree);
        }
Beispiel #8
0
        public void Analyze_ExpressionAccessesOnlyParameter_TreeHasOnlyParameter()
        {
            Expression <Func <Person, Person> > expression = p => p;

            PropertyAccessTree tree = ExpressionPropertyAnalyzer.Analyze(expression);

            Assert.AreEqual(1, tree.Children.Count);
            tree.Children[0].Should().BeOfType <ParameterNode>();
        }
 protected ContinuousSumMonitor(ObservableCollection <Tinput> input,
                                Expression <Func <Tinput, Toutput> > sumFunc)
     : base(input,
            ExpressionPropertyAnalyzer.GetReferencedPropertyNames(sumFunc)[typeof(Tinput)],
            false)
 {
     _sumFunc = sumFunc.Compile();
     ReAggregate();
 }
Beispiel #10
0
 protected ContinuousAverageMonitor(ReadOnlyObservableCollection <Tinput> input,
                                    Expression <Func <Tinput, Tfunc> > averageFunc)
     : base(input,
            ExpressionPropertyAnalyzer.GetReferencedPropertyNames(averageFunc)[typeof(Tinput)],
            false)
 {
     _averageFunc = averageFunc.Compile();
     ReAggregate();
 }
        public void Analyze_ExpressionAccessesOnlyParameter_TreeHasOnlyParameter()
        {
            Expression <Func <Person, Person> > expression = p => p;

            PropertyAccessTree tree = ExpressionPropertyAnalyzer.Analyze(expression);

            Assert.AreEqual(1, tree.Children.Count);
            Assert.IsInstanceOfType(typeof(ParameterNode), tree.Children[0]);
        }
Beispiel #12
0
 protected ContinuousMaxMonitor(ReadOnlyObservableCollection <Tinput> input,
                                Expression <Func <Tinput, Toutput> > maxFunc)
     : base(input,
            ExpressionPropertyAnalyzer.GetReferencedPropertyNames(maxFunc)[typeof(Tinput)],
            false)
 {
     _maxFunc = maxFunc.Compile();
     ReAggregate();
 }
Beispiel #13
0
 protected ContinuousStdDevMonitor(ReadOnlyObservableCollection <Tinput> input,
                                   Expression <Func <Tinput, Tfunc> > devValueSelector)
     : base(input,
            ExpressionPropertyAnalyzer.GetReferencedPropertyNames(devValueSelector)[typeof(Tinput)],
            false)
 {
     _selector = devValueSelector.Compile();
     ReAggregate();
 }
        public static void ExtractPropertyName_WithMultiStepConvertProperty()
        {
            Expression <Func <Person, object> > exp;

            exp = me => me.Brother.Age;

            var propName = ExpressionPropertyAnalyzer.ExtractPropertyName(exp);

            Assert.AreEqual("Age", propName);
        }
        public static void ExtractPropertyName_WithTypedProperty()
        {
            Expression <Func <Person, int> > exp;

            exp = me => me.Age;

            var propName = ExpressionPropertyAnalyzer.ExtractPropertyName(exp);

            Assert.AreEqual("Age", propName);
        }
Beispiel #16
0
 public ContinuousVwapMonitor(ObservableCollection <T> input,
                              Expression <Func <T, double> > priceSelector,
                              Expression <Func <T, int> > quantitySelector)
     : base(input,
            ExpressionPropertyAnalyzer.GetReferencedPropertyNames(priceSelector)[typeof(T)].CombineWith(
                ExpressionPropertyAnalyzer.GetReferencedPropertyNames(quantitySelector)[typeof(T)]),
            false)
 {
     _priceSelector = priceSelector.Compile();
     _qtySelector   = quantitySelector.Compile();
     ReAggregate();
 }
        public void Analyze_ExpressionContainsDelegate_ReturnsPropertyAccessTree()
        {
            Func <Person, string> del = person => person.Name;

            Expression <Func <Person, string> > expression = person => del(person);

            var tree = ExpressionPropertyAnalyzer.Analyze(expression);

            Assert.AreEqual(1, tree.Children.Count);
            PropertyAccessTreeNode parameterNode = tree.Children[0];

            Assert.IsInstanceOfType(typeof(ParameterNode), parameterNode);
            Assert.AreEqual(0, parameterNode.Children.Count);
        }
        public void Analyze_ExpressionUsesMethodCallOnOneLevelProperty_TreeHasOneParameterBranchWithOneProperty()
        {
            Expression <Func <Person, bool> > expression = p => string.IsNullOrEmpty(p.Name);

            PropertyAccessTree tree = ExpressionPropertyAnalyzer.Analyze(expression);

            Assert.AreEqual(1, tree.Children.Count);
            PropertyAccessTreeNode parameterNode = tree.Children[0];

            Assert.AreEqual(1, parameterNode.Children.Count);

            PropertyAccessNode propertyNode = (PropertyAccessNode)parameterNode.Children[0];

            Assert.AreEqual(_nameProperty, propertyNode.Property);
            Assert.AreEqual(0, propertyNode.Children.Count);
        }
        public void Analyze_ExpressionReturnsOneLevelProperty_TreeHasOneParameterBranchWithOneProperty()
        {
            Expression <Func <Person, int> > expression = p => p.Age;

            PropertyAccessTree tree = ExpressionPropertyAnalyzer.Analyze(expression);

            Assert.AreEqual(1, tree.Children.Count);
            PropertyAccessTreeNode parameterNode = tree.Children[0];

            Assert.AreEqual(1, parameterNode.Children.Count);

            PropertyAccessNode propertyNode = (PropertyAccessNode)parameterNode.Children[0];

            Assert.AreEqual(_ageProperty, propertyNode.Property);
            Assert.AreEqual(0, propertyNode.Children.Count);
        }
        public SortingReadOnlyContinuousCollection(IList <TSource> list,
                                                   Expression <Func <TSource, TKey> > keySelectorExpression,
                                                   bool descending)
            : base(list, ExpressionPropertyAnalyzer.Analyze(keySelectorExpression))
        {
            this.KeySelector = keySelectorExpression.CachedCompile();
            this.KeySorter   = new SortsSourceByKey <TSource, TKey>(this.KeySelector, descending);
            SetComparerChain(this.KeySorter);

            BuildItemsInSortOrder(this.Source);

            this.NotifyCollectionChangedMonitor.Add         += OnAdd;
            this.NotifyCollectionChangedMonitor.Remove      += OnRemove;
            this.NotifyCollectionChangedMonitor.Reset       += OnReset;
            this.NotifyCollectionChangedMonitor.Replace     += OnReplace;
            this.NotifyCollectionChangedMonitor.ItemChanged += OnItemChanged;
        }
        public void Analyze_TwoLevelPropertyWhereSubPropertyIsNotINotifyPropertyChanged_TreeContainsFirstProperty()
        {
            Expression <Func <Person, bool> > expression = p => p.Name.Length == 0;

            PropertyAccessTree tree = ExpressionPropertyAnalyzer.Analyze(expression);

            Assert.AreEqual(1, tree.Children.Count);
            PropertyAccessTreeNode parameterNode = tree.Children[0];

            Assert.IsInstanceOfType(typeof(ParameterNode), parameterNode);
            Assert.AreEqual(1, parameterNode.Children.Count);

            PropertyAccessNode nameNode = (PropertyAccessNode)parameterNode.Children[0];

            Assert.AreEqual(_nameProperty, nameNode.Property);
            Assert.AreEqual(0, nameNode.Children.Count);
        }
        public void Analyze_SpecialTypeFilterWithExpressionThatPassesFilter_ReturnsPropertyAccessTree()
        {
            Expression <Func <string, bool> > expression = str => str.Length == 0;

            PropertyAccessTree tree = ExpressionPropertyAnalyzer.Analyze(expression, type => type == typeof(string));

            Assert.AreEqual(1, tree.Children.Count);
            PropertyAccessTreeNode parameterNode = tree.Children[0];

            Assert.IsInstanceOfType(typeof(ParameterNode), parameterNode);
            Assert.AreEqual(1, parameterNode.Children.Count);

            PropertyAccessNode lengthNode = (PropertyAccessNode)parameterNode.Children[0];

            Assert.AreEqual(typeof(string).GetProperty("Length"), lengthNode.Property);
            Assert.AreEqual(0, lengthNode.Children.Count);
        }
        public static BridgeMethod <T> Create <TResult>(Expression <Func <T, TResult> > propertyAccessor)
        {
            MemberExpression memberExpression = ExpressionPropertyAnalyzer.UnwrapLambda(propertyAccessor);

            if (!(memberExpression.Expression is ParameterExpression))
            {
                throw new InvalidOperationException("Extended Properties are not allowed.");
            }

            var name = ExpressionPropertyAnalyzer.ExtractPropertyName(propertyAccessor);

            Action <T> changedCallback  = me => me.OnPropertyChanged(name);
            Action <T> changingCallback = me => me.OnPropertyChanging(name);

            var method = new BridgeMethod <T>(changingCallback, changedCallback);

            return(method);
        }
        public void Analyze_ExpressionContainsDelegateAndPropertyAccess_ReturnsPropertyAccessTree()
        {
            Expression <Func <Person, string> > expression = person => this.StringPassThrough(person.Name);

            var tree = ExpressionPropertyAnalyzer.Analyze(expression);

            Assert.AreEqual(2, tree.Children.Count);

            PropertyAccessTreeNode parameterNode = tree.Children[0];

            Assert.IsInstanceOfType(typeof(ParameterNode), parameterNode);
            Assert.AreEqual(1, parameterNode.Children.Count);

            PropertyAccessTreeNode constantNode = tree.Children[1];

            Assert.IsInstanceOfType(typeof(ConstantNode), constantNode);
            Assert.AreEqual(1, constantNode.Children.Count);
        }
        public void Analyze_ExpressionContainsThis_TreeContainsOneBranch()
        {
            Expression <Func <Person, int> > expression = p => this.TestProperty;

            PropertyAccessTree tree = ExpressionPropertyAnalyzer.Analyze(expression);

            Assert.AreEqual(2, tree.Children.Count);

            PropertyAccessTreeNode constantNode = tree.Children[1];

            Assert.IsInstanceOfType(typeof(ConstantNode), constantNode);
            Assert.AreEqual(this, ((ConstantNode)constantNode).Value);
            Assert.AreEqual(1, constantNode.Children.Count);

            PropertyAccessNode testPropertyNode = (PropertyAccessNode)constantNode.Children[0];

            Assert.AreEqual(GetType().GetProperty("TestProperty"), testPropertyNode.Property);
            Assert.AreEqual(0, testPropertyNode.Children.Count);
        }
        public SelectManyReadOnlyContinuousCollection(
            IList <TSource> list,
            Expression <Func <TSource, IList <TResult> > > manySelector) :
            base(list, ExpressionPropertyAnalyzer.Analyze(manySelector))
        {
            _sourceToCollectionNode = new Dictionary <TSource, List <IndexingSkipList <IList <TResult> > .Node> >();
            _collectionToNode       = new Dictionary <IList <TResult>, List <IndexingSkipList <IList <TResult> > .Node> >();
            _weakEventHandlers      = new Dictionary <IList <TResult>, WeakEventHandler>();
            _collectionIndex        = new IndexingSkipList <IList <TResult> >();

            _selectorFunction = manySelector.CachedCompile();
            RecordCurrentValues(_collectionIndex.TopLeft, this.Source);

            this.NotifyCollectionChangedMonitor.Add         += OnAdd;
            this.NotifyCollectionChangedMonitor.Remove      += OnRemove;
            this.NotifyCollectionChangedMonitor.Reset       += OnReset;
            this.NotifyCollectionChangedMonitor.Move        += OnMove;
            this.NotifyCollectionChangedMonitor.Replace     += OnReplace;
            this.NotifyCollectionChangedMonitor.ItemChanged += OnItemChanged;
        }
        internal GroupingReadOnlyContinuousCollection(
            IList <TSource> list,
            Expression <Func <TSource, TKey> > keySelectorExpression)
            : base(list, ExpressionPropertyAnalyzer.Analyze(keySelectorExpression))
        {
            this.KeySelector = keySelectorExpression.CachedCompile();
            this.Output      = new ContinuousCollection <GroupedReadOnlyContinuousCollection <TKey, TSource> >();

            this.ItemToGroupIndex = new Dictionary <TSource, GroupedReadOnlyContinuousCollection <TKey, TSource> >();

            AddNewItems(this.Source);

            this.NotifyCollectionChangedMonitor.Add         += OnAdd;
            this.NotifyCollectionChangedMonitor.Remove      += OnRemove;
            this.NotifyCollectionChangedMonitor.Reset       += OnReset;
            this.NotifyCollectionChangedMonitor.Replace     += OnReplace;
            this.NotifyCollectionChangedMonitor.ItemChanged += OnItemChanged;

            this.Output.CollectionChanged += OnOutputCollectionChanged;
        }
        public void Analyze_ConditionalExpressionReferencingTwoProperties_TreeContainsOnePropertyBranchWithBothProperties()
        {
            Expression <Func <Person, int> > expression = p => string.IsNullOrEmpty(p.Name) ? p.Age : 0;

            PropertyAccessTree tree = ExpressionPropertyAnalyzer.Analyze(expression);

            Assert.AreEqual(1, tree.Children.Count);
            PropertyAccessTreeNode parameterNode = tree.Children[0];

            Assert.AreEqual(2, parameterNode.Children.Count);

            PropertyAccessNode ageNode = (PropertyAccessNode)parameterNode.Children[0];

            Assert.AreEqual(_ageProperty, ageNode.Property);
            Assert.AreEqual(0, ageNode.Children.Count);

            PropertyAccessNode nameNode = (PropertyAccessNode)parameterNode.Children[1];

            Assert.AreEqual(_nameProperty, nameNode.Property);
            Assert.AreEqual(0, nameNode.Children.Count);
        }
        public FilteringReadOnlyContinuousCollection(IList <TSource> list, Expression <Func <TSource, bool> > expression)
            : base(list, ExpressionPropertyAnalyzer.Analyze(expression))
        {
#if DEBUG
            this.Expr = expression;
#endif
            this.FilterFunction = expression.CachedCompile();

            this.Output     = new ContinuousCollection <TSource>();
            this.ItemLookup = new HashSet <TSource>();

            this.Output.CollectionChanged += RefireCollectionChangedFromOutput;

            AddNewItems(this.Source);

            this.NotifyCollectionChangedMonitor.Add         += OnAdd;
            this.NotifyCollectionChangedMonitor.Remove      += OnRemove;
            this.NotifyCollectionChangedMonitor.Reset       += OnReset;
            this.NotifyCollectionChangedMonitor.Replace     += OnReplace;
            this.NotifyCollectionChangedMonitor.ItemChanged += OnItemChanged;
        }
        public void Analyze_ExpressionReturnsTwoLevelProperty_TreeHasOneParameterBranchWithTwoProperties()
        {
            Expression <Func <Person, int> > expression = p => p.Brother.Age;

            PropertyAccessTree tree = ExpressionPropertyAnalyzer.Analyze(expression);

            Assert.AreEqual(1, tree.Children.Count);
            PropertyAccessTreeNode parameterNode = tree.Children[0];

            Assert.AreEqual(1, parameterNode.Children.Count);

            PropertyAccessNode brotherNode = (PropertyAccessNode)parameterNode.Children[0];

            Assert.AreEqual(_brotherProperty, brotherNode.Property);
            Assert.AreEqual(1, brotherNode.Children.Count);

            PropertyAccessNode ageNode = (PropertyAccessNode)brotherNode.Children[0];

            Assert.AreEqual(_ageProperty, ageNode.Property);
            Assert.AreEqual(0, ageNode.Children.Count);
        }