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:
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.
