Notificar cambios de forma sistematica


En los últimos días me surgió la necesidad de notificar a la vista cada vez que ocurrian cambios en el modelo. La solución rápida, aburrida y repetitiva es la de ir a la clase base del modelo y publicar los eventos. Luego ir a cada clase del modelo y en todos los setters agregar el codigo para notificar el cambio.

Haciendo uso de Reflection, delegates anonimos y generics; implementé otra solución que si bien no es super novedosa, me pareció que vale la pena compartir con ustedes.

La clase base del modelo queda asi:

 6 public class BaseModel
 7 {
 8   protected bool setProperty<T>(object sender, T oldValue, T newValue, setDelegate<T> set)
 9   {
10     if ( oldValue.Equals( newValue ) ) return false;
11
12     string propertyName = String.Empty;
13     StackFrame[] stackFrames = new StackTrace().GetFrames();
14     if (stackFrames != null && stackFrames.Length >= 2)
15     {
16       propertyName = stackFrames[1].GetMethod().Name;
17       propertyName = propertyName.Substring(4, propertyName.Length - 4);
18     }
19
20     bool cancel = false;
21     if ( PropertyChanging != null )
22     {
23       var args = new PropertyChangingEventArgs(oldValue, newValue, propertyName, sender);
24       PropertyChanging( this, args );
25       cancel = args.Cancel;
26     }
27
28     if ( cancel ) return false;
29
30     set(newValue);
31
32     if (PropertyChanged != null)
33     {
34       var args = new PropertyChangedEventArgs(oldValue, newValue, propertyName, sender);
35       PropertyChanged(this, args);
36     }
37     return true;
38   }
39
40   protected delegate void setDelegate<T>(T value);
41
42   public event EventHandler<PropertyChangingEventArgs> PropertyChanging;
43   public event EventHandler<PropertyChangedEventArgs>  PropertyChanged;
44 }

y las clases derivadas quedan así:

 1 /// <summary>
 2 /// Child test model
 3 /// </summary>
 4 public class ChildModel : BaseModel
 5 {
 6   private int age;
 7
 8   /// <summary>
 9   /// Gets or sets the age.
10   /// </summary>
11   /// <value>The age.</value>
12   public int Age
13   {
14     get { return age; }
15     set
16     {
17       setProperty( this, age, value, delegate(int val) { age = val; } );
18     }
19   }
20 }

Como ven, igualmente es necesario modificar las clases derivadas para que los set llamen al metodo heredado. Lo bueno es que toda la lógica de notificación queda en la clase base y cualquier cambio en la misma ya no hay que distribuirla entre las derivadas.

Anuncios

2 comentarios en “Notificar cambios de forma sistematica

  1. Está bueno …. no se puede arreglar el formato para que se lea todo el ancho del código?

    Se me ocurre que se podría delegar (opcionalmente) esto

    if ( oldValue.Equals( newValue ) ) return false;

    para que la clase derivada decida si es necesaria la notificación (en caso que le interese).

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s