José F. Romaniello

Las aventuras y desventuras de un codificador.

I’ve started a project in WPF and I’m learning Caliburn. I really like the way it handle the presentations patterns.
In this post I will show you a way to implement a ModelFramework based model with castle DynamicProxy2.

You can see a basic implementation here (extracted from the Lob Sample for WPF):

If you write your model in this way, you have:
-Automatic INotifyPropertyChanged behaviour.
-Automatic IEditableObject behaviour.
-Automatic n - Undo/Redon behaviour.
-Validations.
-other things.

Note:
I've already implemented the first two features with a Castle IInterceptor’s and DynamicProxy.
I will like to achieve the same result without implementing anything.

This is the model:

public interface ICustomer
{
    string Name { get; set; }
    string Address { get; set; }
}

public interface IEditableCustomerModel : ICustomer, IModel
{}

Note: IModel is from Caliburn.ModelFramework.

The picture:

caliburn.modelframework

The ModelInterceptor class will intercept the properties invocation and use the getvalue and setvalues of the ModelBase target.

The ModelHelper class generates the proxy as follows:

IEditableCustomerModel customerModel = 
    ModelHelper.CreateModel<IEditableCustomerModel, ICustomer>();







This test is working properly:
[Test]
public void can_undo_simple_property_change()
{
    var undoRedoManager = new UndoRedoManager();
    var customerModel = 
        ModelHelper.CreateModel<IEditableCustomerModel, ICustomer>();

    undoRedoManager.Register(customerModel);

    Assert.IsNotNull(customerModel);

    customerModel.Name = "Jose";
    
    customerModel.BeginEdit();

    //First I change the name to "Bill"
    customerModel.Name = "Bill";
    Assert.That(customerModel.Name, Is.EqualTo("Bill"));

    //Ups, No I say "Pedro".
    customerModel.Name = "Pedro";
    Assert.That(customerModel.Name, Is.EqualTo("Pedro"));

    //No, his name is "Andy".
    customerModel.Name = "Andy";
    Assert.That(customerModel.Name, Is.EqualTo("Andy"));


    //No, his name is bill so I will click undo twice.
    //One undo for pedro.
    undoRedoManager.Undo();
    Assert.That(customerModel.Name, Is.EqualTo("Pedro"));
    //Two undo for Bill
    undoRedoManager.Undo();
    Assert.That(customerModel.Name, Is.EqualTo("Bill"));


    //No... HIS NAME IS PEDRO!
    undoRedoManager.Redo();
    Assert.That(customerModel.Name, Is.EqualTo("Pedro"));

    customerModel.CancelEdit();

    Assert.That(customerModel.Name, Is.EqualTo("Jose"));
}

Importat Note: The implementation is working with the castle trunk R5846 thank you Krzysztof Koźmic!!
If you want the full code leave a comment with your email (or private) and I will send you.

kick it on DotNetKicks.com

| More

0 comentarios:

Publicar un comentario en la entrada