clean windows

Creando código más limpio con Fody

June 21, 2013

Hemos hablado anteriormente de como Xamarin nos permite crear aplicaciones móviles multiplataforma utilizando C# y .NET y cómo MvvmCross nos ayudará a reducir la cantidad de código necesaria para poner a funcionar nuestras aplicaciones y optimizar la cantidad de código compartido, dejando un código mucho más legible y limpio.

Ahora bien, si has seguido los tutoriales N+1 de Stuart o tienes experiencia con otros Frameworks MVVM, te habrás dado cuenta que hay mucho código que es exáctamente igual se parece sospechosamente, sobre todo al crear las propiedades de los ViewModels.

Vamos a utilizar como ejemplo el primer tutorial de la serie de N+1 de Stuart, podéis descargar los fuentes del repositorio de Github. En este caso, el código del ViewModel sería el siguiente:

public class FirstViewModel 
	: MvxViewModel
{
    private string _firstName;
    public string FirstName
    {
        get { return _firstName; }
        set { _firstName = value; RaisePropertyChanged(() => FirstName); RaisePropertyChanged(() => FullName); }
    }
 
    private string _lastName;
    public string LastName
    {
        get { return _lastName; }
        set { _lastName = value; RaisePropertyChanged(() => LastName); RaisePropertyChanged(() => FullName); }
    }
 
    public string FullName
    {
        get { return string.Format("{0} {1}", _firstName, _lastName); }
    }
}

Como podrás observar es necesario sobrecargar el setter para que lance el evento RaisePropertyChanged con el fin de notificar a las vistas que el valor ha cambiado. Además hay que declarar el atributo privado interno para cada propiedad que tengamos. Por ejemplo, para la propiedad FirstName hay que declarar también el atributo privado de instancia _firstName.

Si lo que buscas es algo rápido y sucio, puedes simplemente crear una plantilla de Visual Studio como hace Stuart en sus vídeos parecida a esta:

private $classname$ $name$;
public $classname$ $property_name$
{
   get { return $name$; }
   set { $name$ = value; RaisePropertyChanged(() => $property_name$); }
}

Como podrás suponer, el tamaño de los ViewModels crece cuanta más información mostremos en pantalla, si incluyes validación de formularios, lógica de navegación o elementos más complejos, lo que menos te interesa es ver cómo las propiedades lanzan RaisePropertyChanged al ser modificadas. Quieres ver tu código, quieres ver que sea legible, quieres que sea fácilmente mantenible y fácilmente refactorizable.

Ahí es donde Fody viene al rescate. Fody nos trae la Programación Orientada a Aspectos (o AoP por sus siglas en inglés) al desarrollo de aplicaciones C# en .NET, y aunque no está específicamente diseñado para ello, se integra a las mil maravillas con el patrón MVVM y en concreto con el framework MvvmCross. No vamos a entrar a estudiar AoP ni Fody en profundidad, sino cómo nos ayuda a reducir notablemente la cantidad de código necesaria para nuestros ViewModels.

Fody

Utilizando el mismo ejemplo de antes, vamos a incluir Fody para eliminar el código que no sea estrictamente necesario. Fody incluye varios plugins que nos van a ayudar a eliminar la funcionalidad lateral mediante Programación Orientada a Aspectos, pero en este caso concreto el que nos interesa es PropertyChanged.

Para incluir PropertyChanged.Fody a nuestro proyecto únicamente tenemos que incorporar el paquete de NuGet a nuestra librería portable. Simon Cropp, creador de Fody modificó el paquete de NuGet para que fuera 100% compatible con proyectos PCL de MvvmCross, por lo que únicamente debemos realizar la búsqueda en NuGet del plugin PropertyChanged.Fody e incluirlo al proyecto.

Add Nuget Package

 

Pulsando botón derecho sobre el proyecto, seleccionamos Manage Nuget Packages para abrir el gestor de dependencias NuGet, igual que cuando añadimos las dependencias de MvvmCross en los tutoriales anteriores. Una vez abierto el gestor de paquetes, buscamos en el repositorio Online el plugin PropertyChanged.Fody y lo instalamos tal y como se muestra en la siguiente captura.

Add Fody Dependency

Una vez añadido Fody al proyecto, veremos que aparecen dos archivos: Fody.targetsFodyWeavers.xml , el primero hace que tanto Visual Studio como Xamarin Studio ejecuten los plugins de Fody que hayamos instalado, y el segundo archivo indica a Fody qué plugins queremos ejecutar y en qué orden. Este último archivo es importante si queremos ejecutar varios plugins, ya que dependiendo del orden de los plugins conseguiremos un resultado u otro.

Si no hay ningún problema, ya tenemos el plugin PropertyChanged de Fody instalado y funcionando, por lo que podemos pasar a editar el ViewModel, que quedaría de la siguiente forma:

public class FirstViewModel 
	: MvxViewModel
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
 
    public string FullName
    {
        get { return string.Format("{0} {1}", FirstName, LastName); }
    }
}

Como podemos ver, ya no es necesario realizar ningún RaisePropertyChanged, en los setter de las propiedades. Al no ser necesario lanzar el evento manualmente, no es necesario sobreescribir el setter. Al no necesitar sobreescribir el setter, tampoco necesitamos declarar los atributos privados, por lo que la declaración de propiedades en los ViewModels queda únicamente como una declaración de propiedad en una clase normal. Internamente Fody sondea todas las clases del ensamblado tras compilar y busca todas las clases que implementen la interfaz INotifyPropertyChanged y llama al método RaisePropertyChanged (o similar) de la misma clase automáticamente.

Probablemente pienses que es necesario hacer algo más, ya que tanto las propiedades FirstName como LastName también notificaban cambios en la propiedad de sólo lectura FullName. Fody ya ha pensado en eso, e internamente analiza las llamadas que hacen las propiedades a los getters de otras propiedades, creando dependencias entre ellas, de modo que cuando se realiza un cambio en FirstName o LastName, se lanza automáticamente una notificación de cambio sobre la propiedad LastName.

Como no tienes por qué creerme, lo mejor será ejecutar unas pruebas para verificar que todo sigue funcionando como debería.

Fody Sample Screenshot

En la captura podéis ver como todo sigue funcionando como debería tanto en Windows Phone como en iPhone. Aquí se puede ver la magia de Xamarin y MvvmCross en acción, ya que los cambios que hemos hecho se han aplicado en el código compartido, las compilaciones de los proyectos específicos de cada plataforma reflejan automáticamente los cambios hechos en el núcleo sin necesidad de realizar ninguna modificación adicional.

En próximas publicaciones detallaremos algunas de las golosinas que nos trae Fody para evitar otras tareas repetitivas.

 

Por Guillermo Gutiérrez

Categorias: Desarrollo, MvvmCross, Xamarin

  • xleon

    Interesante… parece magia. Pero casi todo lo relacionado con aspectos es medio mágico