Property depencies tracking in CM

Topics: Actions & Coroutines, Conventions, Extensibility, Feature Requests, Framework Services, Getting Started
Nov 11, 2013 at 6:05 PM
Michael L Perry said that

"Automatic dependency tracking means that the framework understands what your code depends upon without you having to be explicit about it. For example, consider a FullName property on the view model:

public string FullName
{
get { return _model.FirstName + " " + _model.LastName; }
}

You don't have to explicitly fire PropertyChanged("FullName") when either FirstName or LastName change. That dependency is automatically discovered."

He said that CM provides this out of the box. But I have created a project a couple of minutes ago and... nope... I didn't discovered such a behaviour of CM out of the box.

Maybe, I don't understand something... Consider the following code:
 ViewModel:
[Export(typeof(MainViewModel))]
    public class MainViewModel:PropertyChangedBase
    {
        private readonly MainModel model;

        public MainViewModel()
        {
            model = new MainModel();
        }

        public string Target
        {
            get { return model.Field1 + model.Field2; }
        }

        public void Test()
        {
            model.Test();
        }
    }
Model:
 public class MainModel:PropertyChangedBase
    {
        private string _field1;
        public string Field1
        {
            get { return _field1; }
            set
            {
                _field1 = value;
                NotifyOfPropertyChange(()=>Field1);
            }
        }

        private string field2;

        public string Field2
        {
            get { return field2; }
            set
            {
                field2 = value;
                NotifyOfPropertyChange(()=>Field2);
            }
        }

        public void Test()
        {
            Field1 = "Hello World!";
        }
    }
Nothing happens when I click button named "Test". The bindings don't work in such a way.
When I add a notification after model.Test() (NotifyOfPropertyChanged(()=>Target)) then all is good.

So the question is: how to follow stateless ViewModel pattern using Caliburn.Micro?
The issue is to notify the ViewModel about changes in the Model as you see. This is a common issue when you are trying to follow "Stateless ViewModel pattern".
Nov 12, 2013 at 6:58 PM
My comment on the Herding Code blog might have been incorrect. The original Caliburn framework had the dependency tracking feature, but it may not have been carried forward to Caliburn.Micro. Rob, please correct me if I'm wrong here.

In Caliburn, the interceptor would inject dependency tracking before every "get" method. If the "get" method for FullName called the "get" method for FirstName, then the "set" method for FirstName would raise PropertyChanged on FullName as well. Your code simply needed to access dependent properties through their property names, not through internal variables.

The dependency tracking mechanism was based on strings, not on instances. As a result, the dependent property had to be in the same class as its precedent. In other words, both FirstName and FullName need to be properties of the view model. Because of this, Caliburn's dependency tracking didn't support the stateless view model pattern, where all of the state is pushed down to the model.