This project is read-only.

Observing Methods

Nov 27, 2009 at 8:28 AM

I'm trying to make an observable expression involving a method call.

Here is a simplified example of my problem:

    public class ObticsTests
    {
        public sealed class Multiplier : INotifyPropertyChanged
        {
            private int factor;
            public int Factor
            {
                get
                {
                    return factor;
                }
                set
                {
                    if (factor == value)
                    {
                        return;
                    }
                    factor = value;
                    OnPropertyChanged("Factor");
                }
            }

            public int Multiply(int value)
            {
                return Factor * value;
            }

            private void OnPropertyChanged(string propertyName)
            {
                var handler = PropertyChanged;
                if (handler != null)
                {
                    handler(this, new PropertyChangedEventArgs(propertyName));
                }
            }

            public event PropertyChangedEventHandler PropertyChanged;
        }

        [Fact]
        public void ExpressionObserver_DetectsChangesInObjectsWhoseMethodsAreCalled()
        {
            var multiplier = new Multiplier();
            var valueProvider = ExpressionObserver.Execute(() => multiplier.Multiply(1));
            
            var eventRaised = false;
            ((INotifyPropertyChanged)valueProvider).PropertyChanged += 
                (sender, e) => { eventRaised = true; };

            multiplier.Factor++;

            Assert.True(eventRaised);
        }
    }
The assert at the bottom fails. Is there a way to tell the value provider that it needs to update when Multiplier.Factor changes?
Nov 30, 2009 at 9:48 AM

Hi,

Assuming that you don't want to change the signature of your Multiply method; this is what you can do:

First you need to create a static method that implements the functionality of Multiply reactively and observably:

public class X
{
    static Func<Multiplier,int,IValueProvider<int>> _Multiply =
        ExpressionObserver.Compile(
            (Multiplier m, int v) => m.Factor * v
        );

    public static IValueProvider<int> Multiply( Multiplier m, int v )
    { return _Multiply(m, v); }
}

Than you can either imperatively register this method with a particular ExpressionObserverObject like in the ObticsToXml project (ObservableExtensions.RegisterMappings method)

or declaratively using the ExpressionObserverMappingAttribute as in the CustomMapping sample project (MyEnumerable class).

Hope this helps.

Regs

Thomas.