> For the complete documentation index, see [llms.txt](https://elguerre.gitbook.io/de0an/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://elguerre.gitbook.io/de0an/capitulo-04-la-construccion.-los-cimientos/mvvm-conceptos-generales-y-eleccion.md).

# MVVM: Conceptos Generales y elección

En el capítulo dos conocimos los requerimientos y capacidades de hardware y software, las APIs de desarrollo, la interfaz de usuario y todos sus controles. En esta sección, comprenderemos el patrón de desarrollo MVVM (Modelo Vista Vista-Modelo o *Model View ViewModel*). Haremos algunas comparativas entre distintos *Toolkit* con el fin de elegir el que más se adapte a nuestras necesidades, y, echaremos un vistazo a los contendedores de *IoC (Inversión de Control)*.

MVVM no es ni más ni menos que la evolución del patrón MVC (“Model View Controller”) donde **programadores y diseñadores pueden trabajar en paralelo**. Esta es la clave de la potencia del patrón.

MVVM abstrae el código (*code-behind*) asociado a la vista (XAML) en clases independientes. El quid de todo ello radica en los "**Bindings**" (propiedades de enlace a datos que proporciona el código XAML).

En la siguiente figura podemos ver un esquema del patrón:

![](https://240651724-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FfrvHBNivOTy0fVKROgzo%2Fuploads%2Fgit-blob-fa6062f75f77ddcc74a453f9cbf2797e5afb3438%2Fimage5.png?alt=media)

**Figura 05.- Patrón MVVM (Model View View-Model)**

* **Vista**. Código declarativo XAML y código asociado (o *code-behind)*. El patrón MVVM intenta reducir al máximo el uso del código trasladándolo a la Vista-Modelo. El uso de enlace a datos (o *data bindings*) y comandos (o *commands*) facilitan esta labor.
* **Vista-Modelo**. Lógica para el tratamiento de los datos proporcionados por el modelo. Principalmente: Propiedades, comandos y servicios (clases de abstracción para el almacenamiento e interacción con las capacidades del dispositivo).
* **Modelo**. Gestiona la información proporcionada por el *Backend*. En la mayoría de los casos, servicios web y de tipo **REST**[²](/de0an/capitulo-04-la-construccion.-los-cimientos/que-hemos-aprendido.md#notas).

MVVM es utilizado con Xbox, IoT, Holo Lens, WPF, Silverlight, Windows Store, Windows Phone, y, en general, en cualquiera de las aplicaciones desarrolladas con UWP y *Xamarin*[³](/de0an/capitulo-04-la-construccion.-los-cimientos/que-hemos-aprendido.md#notas).

## Diferentes implementaciones y una elección.

Cuando hacemos uso del patrón MVVM, como desarrolladores que somos, siempre terminamos por hacer algunas adaptaciones a nuestro gusto. Así, sin dejar de lado las buenas prácticas y recomendaciones de su implementación, conseguimos sentirnos más cómodos y ágiles.

De la misma manera podemos encontrar numerosas implementaciones o *frameworks;* con sus propias plantillas de proyecto para Visual Studio, *code snippets*, *toolkits*, etc. Facilitándonos ciertas tareas repetitivas, y ofreciéndonos una mayor abstracción y sencillez de la implementación del patrón. Nos centraremos en tres de ellas: Mvvm Light, Caliburn.Micro y MVVMCross.

Analizando las tendencias en el momento de escribir el libro, Google nos dice lo siguiente:

![](https://240651724-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FfrvHBNivOTy0fVKROgzo%2Fuploads%2Fgit-blob-e4011a951e66a62bcd64f25b156dce106f3ad5d9%2Fimage6.png?alt=media)

**Figura 06.- Tendencia de uso en los últimos cinco años**

![](https://240651724-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FfrvHBNivOTy0fVKROgzo%2Fuploads%2Fgit-blob-b3223d438c7dd5e320190a86c2fec1cdbba0312b%2Fimage7.png?alt=media)

**Figura 07.- Tendencia de uso en el último año**

![](https://240651724-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FfrvHBNivOTy0fVKROgzo%2Fuploads%2Fgit-blob-f219426ce254e24d48501efba61a37591dcd6dc8%2Fimage8.png?alt=media)

**Figura 08.- Tendencias de uso los últimos 90 días**

Tras observar estas gráficas y de modo resumido podemos decir que, aunque parece que en el último año MVVMCross ha sido el más popular, MVVM Light se mantiene en el tiempo además de que en los últimos tres meses sigue estando a la cabeza. En la siguiente tabla podemos ver más datos recogidos desde *nuget.org*:

**Tabla 1.- Comparativa de Implementaciones de Patrones MVVM**

| MVVM           | Descargas | Licencia | URL                                     |
| -------------- | --------- | -------- | --------------------------------------- |
| MVVM Light     | 973.826   | MIT      | <https://github.com/lbugnion/mvvmlight> |
| Caliburn Micro | 329.326   | MIT      | <https://caliburnmicro.com/>            |
| MVVM Cross     | 136.190   | MS-PL    | <https://mvvmcross.com/>                |

Es probable que MVVMCross, esté adquiriendo relevancia últimamente gracias a los desarrollos multi-plataforma con Xamarin y que, MVVM Light lleve mucho más tiempo en NuGet, pero, en cualquier caso, podemos concluir que **MVVM Light** tiene mayor número de descargas y mayor índice de popularidad entre los desarrolladores. Además de caracterizarse por su facilidad de uso y aprendizaje, por lo que es **el candidato perfecto** para nuestro proyecto.

Esto no significa que sea mejor que el resto, cada uno tiene su particularidad y es recomendable valorar detenidamente cada uno de ellos. Dependerá de los requisitos de cada aplicación entre otros factores.

## Inversión de control e Inyección de dependencias

La inversión de Control (o, *Inversion of Control*), conocida también como **IoC**, es un método de programación en el que el flujo de ejecución de un programa se invierte respecto al método tradicional. Es decir, en IoC, en lugar de realizar llamadas a funciones o procedimientos, se especifican respuestas concretas a situaciones concretas y, es una entidad o arquitectura externa, quien realiza la ejecución y las acciones de control necesarias. Se trata de una implementación del **Principio de Hollywood**, una metodología de diseño de software, cuyo nombre proviene de las respuestas típicas que se les dan a los actores amateurs en las audiciones: *no nos llames; nosotros te llamaremos*.

Inyección de Dependencias (*o Dependency Injection*), abreviado como ID o DI, es un patrón de diseño orientado a objetos, en el que se suministran objetos a una clase en lugar de ser la propia clase quien los cree. Consiste en inyectar comportamientos a componentes, es decir, extraer responsabilidades de un componente para delegarlas en otro, estableciendo un mecanismo a través del cual el nuevo componente puede cambiar en tiempo de ejecución.

Su implementación consiste en un "Contenedor de inyección de dependencias" y objetos planos o simples (objetos POCO en .NET), donde el contenedor inyecta a cada objeto otros objetos necesarios y es implementado por un *framework* externo a la aplicación. Por tanto, en la aplicación, también se utilizará inversión de control al ser el contenedor, el encargado de invocar al código de la misma.

{% hint style="info" %}
**Nota**: La ID, es una forma de IoC, que hace uso de la modularidad y la reutilización de componentes e intenta junto con la propia IoC, solucionar los problemas de dependencia (acoplamiento) entre componentes.
{% endhint %}

Cuando hablamos de MVVM implícitamente también lo estamos haciendo de ID e IoC y, por consiguiente, de las dependencias entre *View* y *ViewModels*, que es donde mayor número existen habitualmente. Para la gestión de éstas, existen numerosos *frameworks* de inyección de dependencias compatibles con UWP: *Unity*, *Autofac*, *Ninject*, *MicroIoC*, *SimpleInjector*, etc., donde cada uno de ellos tiene sus peculiaridades, ventajas e inconvenientes. Para nuestra aplicación, optaremos por el contenedor de ID (también llamado contenedor de dependencias) que ya ofrece MVVM Light, es decir, ***SimpleIoc***. Es muy básico, pero a la misma vez, fácil de usar y ligero.

{% hint style="info" %}
**Nota**: MVVM Light usa *Microsoft.Practices.ServiceLocation.ServiceLocator* lo que nos facilitará el uso de cualquier otro contendor de ID. Simplemente, implementando la interfaz *IServiceLocator* y utilizando cualquiera de los contenedores comentados.
{% endhint %}
