Traducción aproximada del artículo Simple ViewModel Locator for MVVM: The Patients Have Left the Asylum por John Papa publicado el 30 de marzo del 2010

 

Últimamente he estado jugando con varias ideas relacionadas con MVVM. De camino he venido arrastrando a amigos como Glenn Block y Ward Bell. A primera vista no parece gran cosa, pero es que cuando se me mete una idea que desafía lo que es aceptado como correcto, se hace “interesante” trabajar conmigo. :) Estos chavalos son muy buena gente y les recomiendo llegar obtener los muñecos con cabeza de resorte de Glen y Ward para poner en su casa.

Pero volviendo a MVVM… he estado explorando de nuevo el universo de la vista primero. La idea es simple: la vista es creada y esta a su vez crea el modelo de vista en el XAML. No es difícil cuando el modelo de vista es creado como un recurso estático de la vista en XAML, pero se complica un poco si uno quiere que el modelo de vista esté activo en la superficie de diseño de Cider o Blend.

La secuencia es importante, lo que yo quiero es crear la vista primero, luego el modelo de vista y usar datos de muestra durante la etapa de diseño. Una opción es usar un localizador de modelos de vista.  (usando el patrón de diseño Localizador de servicios). La opción funciona y es usada en el MVVM Light Toolkit (una excelente biblioteca liviana para MVVM). Lo que no me gusta es la cantidad de trabajo envuelta en administrar el localizador. De ahí es que surgió mi actitud de “rebelarme contra todo lo que ya sé”.

Al principio empecé a conversar con Glenn Block sobre cómo usar MEF para hacer que el localizador de modelos de vista fuese completamente genérico. Mi plan era sacarlo del cuadro y hacerlo súper simple. Así que, tras persuadir a Glenn con algunos comentarios animadores, nos embarcamos en una tanda de codificación en pareja por más de una hora. El resultado es este artículo de blog, con todo y posibles defectos. Pueden descargar el código de ejemplo al final del texto.

Estos son los pasos (luego de agregar una referencia al DLL del localizador):

  1. Crear el ViewModelLocator en App.xaml como un recurso estático.
  2. Exportar el modelo de vista usando un atributo especial (esto lo hace visible al localizador).
  3. Asignar el ViewModelLocator al DataContext de la vista y enlazarlo al modelo de vista usando un número de índice.

 

Paso 1: Crear el ViewModelLocator en App.xaml como un recurso estático

Lo que deseo en realidad es poder producir fácilmente modelos de vista. Es buena idea empezar discutiendo cómo usar el ViewModelLocator. Viene en una biblioteca DLL por lo que no hay necesidad de tocar ese código (a menos que intencionalmente quieran hacerlo). El siguiente código es necesario sólo una vez en mi aplicación. Lo hace es crear el objeto ViewModelLocator en el archivo App.xaml.

 

<Application.Resources>
  <MVVMLib:ViewModelLocator x:Key="VMLocator"/>
  <MVVMLib:IndexerConverter x:Key="VMIndexerConverter" />
</Application.Resources>

 

Noten que también he creado un convertidor. Su único propósito es lidiar con un defecto en Silverlight 4 que surge al tratar de enlazar un indexador de cadenas. El problema es que crea el enlace seis veces. El convertidor sirve de solución temporal; una vez que el defecto sea reparado, ya no se ocupa.

 

Paso 2: Exportar el modelo de vista usando un atributo especializado

Abajo tengo un modelo de vista (bastante insípido por cierto) en el que lo único que hago es exportarlo usando una cadena como identificador. Esto le ayuda a MEF a identificarlo.

 

[ExportViewModel("MainPageViewModel")]
public class MainPageViewModel : ViewModelBase
{
    private string _companyName;
    public string CompanyName
    {
        get { return "Contoso, Inc."; }
        set
        {
            _companyName = value;
            FirePropertyChanged("CompanyName");
        }
    }

}

 

 

Paso 3: Asignar el ViewModelLocator al DataContext de la vista y usar un número de índice para enlazar el modelo de vista deseado

El último paso es asignar el ViewModelLocator al DataCentext de la vista y usar un número de índice para decirla cuál modelo de vista usar.

 

DataContext="{Binding
  Source={StaticResource VMLocator},
  Converter={StaticResource VMIndexerConverter},
  ConverterParameter=MainPageViewModel}"

 

De nuevo, el código es un poco más complejo de lo que debería por el defecto que mencioné antes. Si el enlace se efectuara una vez en vez de seis, podríamos evitar el convertidor. El siguiente es un ejemplo mucho más claro sin ese elemento extra. De fijo es más atractivo.

 

DataContext="{Binding
    Source={StaticResource VMLocator},
    Path=Find[MainPageViewModel]}"

 

¡Y eso es todo! Todavía es posible usar Blend de diversas maneras, una de ellas sería usar el siguiente código si lo prefieren.

 

d:DataContext="{d:DesignInstance
    Type=VMLocatorDemo:MainPageViewModelDesign,
    IsDesignTimeCreatable=True}"

 

 

¿Y si tengo montones de vistas y modelos de vistas?

Buena pregunta. Aquí es donde más me gusta esta solución. No hay más que repetir los pasos 2 y 3, exportando el modelo de vista y asociándolo a la vista. Muy, muy simple.

 

¿Algo más que deba saber?

Es posible crear un nuevo modelo de vista cada vez que se use. También se puede crear un modelo de vista único usando el patrón singleton para reutilizarlo. Usando el código que escribí pueden usar el método Find para crear nuevas instancias o el método FindShared para usar una instancia única.

 

¿Dónde encuentro el código?

Pueden obtener el código fuente del ViewModelLocator que escribí con Glenn Block aquí. También incluyo una demostración para que lo prueben. La intención es resaltar lo que es posible hacer y cómo lograr que el localizador sea fácil de usar y administrar. El plan es reorganizarlo y ver si se puede simplificar o limpiar un poco. También planeamos examinar el indexador de cadenas a ver si podemos eliminar el convertidor.

Pero descarguen el código, por favor, y dejen sus comentarios. ¡Estamos ansiosos de oír sus ideas!

 

John Papa

 

Etiquetas asignadas:
 

1 Respuesta » a “Sencillo localizador de modelos de vista para MVVM: los pacientes han abandonado el manicomio”

  1. [...] Sencillo localizador de modelos de vista para MVVM: los pacientes han abandonado el manicomio [...]

Responder



Licencia de uso

El contenido de las traducciones está sujeto a los términos de protección de derechos de uso de los autores originales quienes han autorizado su publicación en este blog. Asegúrese de entender los terminos de la licencia de cada autor antes de usar tal contenido.

Mis propios artículos son publicados bajo los términos de la Licencia Reconocimiento-Compartir bajo la misma licencia 3.0 Estados Unidos de Creative Commons:

Creative Commons License
Blog de Maromas Digitales by Maromas Digitales, LLC is licensed under a Creative Commons Reconocimiento-Compartir bajo la misma licencia 3.0 Estados Unidos License.

License

The contents of all translated articles is subject to the copyright and licensing terms of the original authors and has been published here with their express permission. Verify the original author's licensing terms before using the contents of these articles.

My own articles are licensed under the Creative Commons Attribution-Share Alike 3.0 United States License:

Creative Commons License
Blog de Maromas Digitales by Maromas Digitales, LLC is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.