Según el enfoque tradicional o teoría sabia, ViewModel debe ser parte de capa de interfaz de usuario. Al menos el nombre lo dice.
Pero cuando se llega a la implementación de usted mismo con Entity Framework, MVC, depósito, etc., entonces te das cuenta de algo más.
Alguien tiene que asignar Modelos Entidad/DB con ViewModels (DTO menciona en el final). ¿Debería hacerse esto en [A] la capa UI (por el Controlador), o en [B] la capa Servicio?
Voy con la opción B.La opción A es un no no por el simple hecho de que varios modelos de entidades se combinan para formar un ViewModel. Es posible que no pasemos datos innecesarios a la capa UI, mientras que en la opción B, el servicio puede jugar con datos y pasar solo el nivel requerido/mínimo a la capa UI después del mapeo (al ViewModel).
De nuevo, vamos a ir con la opción A, poner ViewModel en la capa de UI (y el modelo de entidad en la capa de Servicio).
Si la capa de servicio necesita correlacionarse con el modelo de vista, entonces la capa de servicio necesita acceder a ViewModel en la capa de interfaz de usuario. ¿Qué biblioteca/proyecto? El modelo de vista debe estar en un proyecto separado en la capa de la interfaz de usuario, y este proyecto debe ser referenciado por la capa de servicio. Si ViewModel no está en un proyecto separado, entonces hay una referencia circular, así que no vayas. Parece incómodo tener la capa de servicio accediendo a la capa de interfaz de usuario, pero aún así podemos hacer frente a ella.
Pero, ¿qué ocurre si hay otra aplicación UI que utiliza este servicio? ¿Qué pasa si hay una aplicación móvil? ¿Qué tan diferente puede ser ViewModel? ¿Debe el Servicio acceder al mismo proyecto de modelo de vista? ¿Todos los proyectos de UI accederán al mismo proyecto de ViewModel o tendrán el suyo propio?
Después de estas consideraciones, mi respuesta sería poner el proyecto Viewmodel en la Capa de servicio. ¡Cada capa de interfaz de usuario tiene que acceder a la capa de servicio de todos modos! Y podría haber muchos ViewModels similares que todos podrían usar (por lo tanto, la asignación se vuelve más fácil para la capa de servicio). Las asignaciones se realizan a través de linq en estos días, lo cual es otra ventaja.
Por último, hay esta discusión sobre DTO. Y también sobre la anotación de datos en ViewModels. Los modelos ViewModels con anotaciones de datos (Microsoft.Web.Mvc.DataAnnotations.dll) no pueden residir en la capa de servicio sino que residen en la capa UI (pero ComponentModel.DataAnnotations.dll puede residir en la capa de servicio). Así que DTO en realidad es un ViewModel porque en su mayoría habrá un mapeo uno a uno entre los dos (digamos con AutoMapper). Una vez más, DTO sigue teniendo la lógica necesaria para la interfaz de usuario (o múltiples aplicaciones) y reside en la capa de servicio. Y la capa de interfaz de usuario ViewModel (si usamos Microsoft.Web.Mvc.DataAnnotations.dll) es solo para copiar los datos de DTO, con algunos 'comportamientos'/atributos añadidos.
[Ahora bien, esta discusión está a punto de dar un giro interesante leer sobre ...: I]
Y no creo que los atributos de anotación de datos son sólo para la interfaz de usuario. Si limita la validación utilizando System.ComponentModel.DataAnnotations.dll , entonces el mismo modelo de vista también se puede usar para la validación de back-end front-end & (eliminando así UI-residing-viewmodel-copy-of-DTO). Más de los atributos también se pueden usar en modelos de entidades. Por ejemplo, al utilizar .tt, los modelos de datos de Entity Framework pueden autogenerarse con atributos de validación para realizar algunas validaciones de db, como max-length, antes de enviarlas al back-end. Otra ventaja es que si la validación de back-end cambia en DB, entonces .tt (lee las especificaciones de db y crea un atributo para la clase de entidad) lo recogerá automáticamente. Esto puede obligar a las pruebas de la unidad de validación UI a fallar también, lo cual es una gran ventaja (para que podamos corregirlo e informar a todas las UI/consumidores en lugar de olvidar y fallar accidentalmente). Sí, la discusión se está moviendo hacia un buen diseño del marco. Como puede ver, todo está relacionado: validación de nivel, estrategia de prueba de unidad, estrategia de almacenamiento en caché, etc.
Aunque no está directamente relacionado con la pregunta. 'ViewModel Façade' mencionado en esto debe mirar channel 9 link también vale la pena explorar. Comienza exactamente a los 11 minutos y 49 segundos en el video. Porque este sería el próximo paso/pensamiento una vez que se resuelva su pregunta actual dada arriba: '¿Cómo organizar viewmodels?'
También en su ejemplo "_repository.ListContacts()" está devolviendo un modelo de vista del repositorio. Esta no es una forma madura. Los repositorios deben proporcionar modelos de entidades o modelos db. Esto se convierte para ver modelos y es este modelo de vista el que devuelve la capa de servicio.
Es posible que también desee echar un vistazo a http://weblogs.asp.net/scottgu/archive/2009/04/28/free-asp-net-mvc-nerddinner-tutorial-now-in-html. aspx –
El tutorial de NerdDinner es el peor lugar para buscar esta información. Es genial para demostrar las características de MVC, pero la arquitectura que implica es horrible. – Aaronaught
@Aaronaught ya que al parecer eres un experto, ¿cuál es tu tutorial en profundidad sobre la arquitectura correcta de MVC? –