Busqueda local

Loading

viernes, 11 de noviembre de 2011

MVP en ASP.NET usando Entity Framework (2 de 3)

En un artículo que publique en Marzo de este año, hable del patrón Service Locator, en ese entonces les presente un ejemplo cuyo contexto podía parecer un poco forzado o abstracto, en esta ocasión usaremos el mismo patrón para nuestro ejemplo de MVP.
Y veremos de qué forma interactuar con el proyecto de presentación…

Casamiento por Separación de bienes.

Cada quien lo suyo. Cuando se crea una aplicación que debe interactuar con el usuario, para ser alimentada por este, es normal pensar que la estructura de las tablas, representa los datos que el usuario ve en las UI; esto nos lleva a usar mecanismos que hacen cohesiva nuestra UI con los datos que representan.
Aquellos datos que no debe ver el usuario los omitimos, como podrían ser los campos lave o las relaciones, pero todo lo demás si se convierte en algún control para que el usuario pueda interactuar con esta información.
La experiencia me dará la razón, cuando tenemos que modificar algo a nivel de datos, es un terremoto de 8 en la escala de Ritchter, que afecta todo nuestro desarrollo, debemos mover rápidamente lo que hemos programado, por de lo contrario la aplicación corre peligro.
 

Como podemos hacer para que la UI y las entidades no se hagan cohesivas?

Es un patrón que nos permite separar el modelo de la interface de usuario.
Desde mi muy particular punto de vista un ViewModel es una forma de organizar los datos que pertenecen a un modelo para que puedan ser presentados sin tener que exponer la entidad, incluso aun que dicha entidad no exista en la base de datos.
 

Analicemos porque existe?

Según el patrón las entidades pertenecen al MODEL y contienen propiedades que pueden estar relacionadas a campos en la base de datos o simplemente ser propiedades que no existen en la base de datos y que sirven para la lógica de la aplicación. Entonces cuando debemos enviar los datos al View, puede resultar pesado enviar una entidad del MODEL donde hay información de más.
mvpentity16
Eso no es todo, para que resulte más complejo, cuando estamos creando un View resulta que se deben enviar algunos datos que ni son de la base de datos, ni son propiedades de ninguna entidad, por lo tanto no se emplean para uso de la lógica de negocios; son propiedades que deben existir para poder representar los datos apropiadamente en la View y no tienen sentido para nadie más. 
 

Doble trabajo?

Podría parecernos doble trabajo, sobre todo si estamos acostumbrados a la forma que comentamos al principio, pero a la larga si usamos ViewModels en vez de las entidades, lograremos separar adecuadamente las responsabilidades de cada parte.
 

Continuación

Así que dicho lo anterior, vamos a empezar por crear nuestro primer ViewModel, para la empresa, por lo que deben crear una carpeta llamada ViewModels dentro de la carpeta model y agregar la siguiente clase dentro:
mvpentity17
Si comparan la estructura de datos con la tabla que creamos en el articulo previo, podrán ver que no hemos incluido todos los campos, simplemente usaremos los que se necesitan para llevar la información a nivel de la capa del UI.
 

Como movemos los datos de las entidades hacia el ViewModel?

Si han comprendido lo que estamos haciendo, entonces la pregunta que use como sub titulo de este párrafo, es la más obvia para hacer en este momento.
Si han llegado hasta aquí, entonces sus entidades residen dentro de un archivo de código que acompaña al Model:
mvpentity18
Este código que se genera por la herramienta, no debe ser modificado, por que la próxima vez que se compile la aplicación, podría volver a generarse y se perdería nuestro trabajo.
Para solucionar este problema contamos con los métodos de Extensión, los cuales nos permiten extender lo que ofrece una clase, sin tener que tener el código fuente; así que ahora deben crear una carpeta que llamaremos Extensions dentro del Model:
mvpentity19
Según la lógica que hemos comentado vamos a necesitar de dos métodos de extensión, uno para convertir una entidad empresa a un ViewModel y otro que nos permita convertir una lista de Empresas en una lista de ViewModels.
mvpentity20
mvpentity21
Es muy importante para que funcione que se encuentren en el mismo espacio de nombres que las entidades, o sea Model.
 

Servicios

El software basado en servicios, no es algo nuevo, ha sido la forma en que se desarrollan aplicaciones por mucho tiempo, en este concepto donde los datos se centralizan, y las aplicaciones solicitan al software que atienda tareas específicas.
A gran escala hay muchos ejemplos, sin embargo en esta ocasión estamos hablando de un componente dentro de nuestra aplicación que se encargara de recibir las solicitudes para la creación controlada de los servicios, cada vez que se requiera una instancia se la solicitamos a este único servicio y este atenderá nuestras necesidades.
De esta forma la creación de las instancias se encuentra controlada, y agregar nuevos servicios solo afecta al código de un lado de la relación.
 

Continuemos

Agreguen una carpeta llamada Servicios al mismo nivel que la carpeta del Model y agreguen dentro dos capetas más denominadas, Interfaces y Services:
mvpentity13
Dentro de Interfaces vamos a crear las siguientes Interfaces:
mvpentity14mvpentity15
Ahora vamos a crear nuestro servicio para las empresas, el cual debe quedar dentro de la carpeta services:
mvpentity22
Debe implementar nuestra interface, como lo indica el recuadro rojo.
Ahora veamos el código que se encontraba oculto:
Propiedades.
mvpentity23
Inyección de dependencia:
mvpentity24
Método que obtiene los datos:
mvpentity25
Observen como se emplea el método de extensión después del método GetAll el cual nos regresa una lista de empresas.

Nuestro Service Locator

Para esta parte solo nos falta implementar nuestro Servicio centralizado usando el patrón de Serice Locator:
mvpentity26
Presten especial atención a la implementación del patrón Singleton en la parte encerrada en el recuadro rojo. El método encerrado en amarillo, se encuentra en l código auxiliar, que veremos a continuación:
mvpentity27
En este método se registran los servicios que puede entregar nuestra clase, que no es otra cosa, que agregar definición de instancias (ojo: no se crean en ese momento) para que sean creadas, cuando se solicite. Como lo demuestra el siguiente código:
mvpentity28
Para poder llevar a cabo la tarea, de crear instancias a partir de las definiciones que hemos registrado, es necesario hacer uso de la técnica de Reflection, como se puede observar en el recuadro rojo.
En este código deben prestar especial atención a lo que se hace en el recuadro amarillo, se verifica si ha sido creada la instancia, para que le devolvamos una referencia a la misma, en vez de crear otra nueva.
 

Continuara….

Aclaración: Quiero comentarles que al empezar el artículo anterior, creí que con dos podría cubrir la explicación del ejemplo, pero mientras me encontraba escribiendo este, me di cuenta, que era así, por lo que cambie el titulo del anterior y extendí un articulo mas para este ejemplo, por lo cual serán 3.
En el próximo veremos cómo se lleva a cabo la presentación de la información en la UI.
Y recuerden: El poder del código solo es completo, si tenemos el conocimiento de cómo usarlo.

No hay comentarios:

Publicar un comentario