This project is read-only.
Using SpiritMVVM, a developer can quickly and declaratively create a property dependency map for a ViewModel.

A property dependency occurs whenever one property's value changes, based on another property's value. An example from an MVVM perspective would be as follows; when property A "Depends On" another property B, that means that any time property B is changed, the "PropertyChanged" event should be raised for both A and B.

This should not be limited only to direct dependencies. Taking the example further; if property A "Depends On" property B, and property B "Depends On" property C, then any time property C is changed, the "PropertyChanged event should be raised for all 3 properties: A, B, and C.

In SpiritMVVM, these event notifications between dependent properties are automatically handled, once the map has been declared by the developer. Declaring dependencies can be achieved in two ways.

Aspect-Oriented: The "DependsOn" Attribute

public class MyViewModel : ViewModelBase
{
    // PropA depends on PropB
    [DependsOn("PropB")]
    public int PropA
    {
        get { return PropB + 1; }
    }

    // PropB depends on PropC
    [DependsOn("PropC")]
    public int PropB
    {
        get { return PropC + 1; }
    }

    private int _propC;
    public int PropC
    {
        get { return _propC; }
        set { Set(ref _propC, value); }
    }
}

This approach is beneficial because the dependencies can be declared statically, and the dependencies can be easily gleaned by simply looking at a property's attributes. The downside to this approach is that Lambda functions cannot be used in an Attribute declaration, so String values must be used instead.

Fluent Syntax

public class MyViewModel : ViewModelBase
{
    public MyViewModel()
    {
        // PropA depends on PropB
        Property(() => PropA)
            .DependsOn(() => PropB);

        // PropB depends on PropC
        Property(() => PropB)
            .DependsOn(() => PropC);
    }

    public int PropA
    {
        get { return PropB + 1; }
    }

    public int PropB
    {
        get { return PropC + 1; }
    }

    private int _propC;
    public int PropC
    {
        get { return _propC; }
        set { Set(ref _propC, value); }
    }
}

The fluent syntax approach creates clean and readable dependency maps, which can be chained together for a single property:
Property(() => PropA)
    .DependsOn(() => PropB)
    .DependsOn(() => PropD);
In this example, PropA is dependent on both PropB and a new property, PropD.

The primary benefit of this approach is: dependencies created using the fluent syntax can be created on the fly, at run-time, and can differ between multiple instances of the same class. On top of that, because the Fluent syntax supports Property arguments as lambda expressions, you have the safety of strongly-typed arguments, as opposed to the raw strings used by the DependsOn attribute.

These two approaches can be combined; a developer can map static dependencies using the "DependsOn" attribute, and optionally create run-time dependencies using the Fluent Syntax approach.

Last edited Oct 31, 2013 at 3:18 PM by btowntkd, version 6

Comments

No comments yet.