2010-04-27 12 views
12

Estoy usando la arquitectura S # arp, y no recuerdo dónde la leí, pero dicen que ViewModels debe almacenarse en la capa de servicio, y sus vistas deben enviar el modelo de vista al servicio para su procesamiento.¿Qué capa debería construir un Modelo de visualización?

Mi pregunta es esta. ¿Qué capa debería construir ViewModel? ¿Debería estar en la capa de servicio y el controlador lo solicita? ¿O debería el controlador construirlo por sí mismo? También hay una pregunta sobre la actualización del modelo de vista, ya que si contiene colecciones, y el estado del modelo no es válido, también necesitará volver a publicar las listas.

¿Alguna sugerencia?

Muchas gracias

Matt

Respuesta

8

que crear modelos de vista dentro de los controladores. Los controladores toman entidades de dominio (recuperadas de la base de datos por carpetas modelo), posiblemente dentro de otros modelos de vista, repositorios de contacto para datos adicionales, crean un nuevo modelo de vista y lo pasan a la vista apropiada (o redirigir). Por lo tanto, la responsabilidad de los controladores es preparar la vista/el modelo de vista de acuerdo con los datos del dominio de entrada (y manejar los errores por supuesto).

Puede buscar here como alternativa a la creación de modelos de visualización en el controlador. Esta técnica mueve la creación del modelo de vista fuera de las acciones, de modo que no solo las acciones del controlador aceptan objetos de dominio puro, sino que también devuelven objetos de dominio puro. No diría que es apropiado en todos los casos, pero es muy interesante de aprender.

La técnica anterior, relacionada con AutoMapper, también generó preguntas similares a "debería pasar los modos de vista a la capa de servicio". No, no lo haces. Si necesita pasar un objeto complejo a un servicio o capa de dominio, defina este objeto en la capa de servicio/dominio apropiada y úselo para pasar datos a esas capas. Este objeto se puede asignar fácilmente a/desde modelos de vista (por ejemplo, usando AutoMapper). Pero las capas inferiores (servicio/dominio) no deben acoplarse a las capas superiores (vista/controladores). No en este caso, no en otros. Nunca las capas de bajo nivel deben depender de algo definido por encima de ellas.

+0

Eso es más o menos lo que estoy haciendo ahora, pero debo estar haciendo algo mal, ya que parece que tengo mucha lógica condicional cuando me ocupo del modelo de vista de vuelta al dominio. Tal vez necesito dividir mi vista en trozos más pequeños. –

+0

Actualmente tengo una vista de edición que adapta en función del estado de la entidad. ¿Sería mejor crear vistas múltiples para los diferentes estados? –

+0

Sin ver su vista de edición y sus modelos, es difícil de responder. – queen3

3

Estos artículos podrían ser interesantes para usted:

DDD : Command Query Separation as an Architectural Concept

Better Application Services and CQS using S#arp Architecture

No es un ejemplo de aplicación asociado con el segundo artículo que tiene la vista y forman modelos en una capa de servicios, en lugar de el controlador.

+1

Esta es la respuesta correcta. Sin embargo, normalmente empiezo con ViewModel en el controlador y lo migro a la capa de servicio a medida que el controlador evoluciona. –

+0

Los enlaces están caídos, quizás http://sharp-architecture.readthedocs.io/en/latest/additional-resources/additional-information.html ayude? – kristianp

0

también mira Who Can Help Me - es fantástico. este marco se basa en S # arp Architecture. tiene mucha orientación para View/Form/Edit viewModels, entre otras cosas.

11

Según el enfoque tradicional o la teoría correcta, ViewModel debe ser parte de la capa de interfaz de usuario. Al menos el nombre lo dice.

Pero cuando empiezas a implementarlo tú mismo con Entity Framework, MVC, Repository, etc., entonces te das cuenta de algo más.

Alguien tiene que mapear Modelos de entidad con ViewModels (DTO mencionado al 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 debido al 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).

Pero, supongamos que vamos con la Opción A, ponemos 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? o ¿competirán todos los proyectos de UI?

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. ViewModels con anotaciones de datos no puede residir en la capa de servicio. Entonces DTO será una copia exacta de ViewModel con 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 es solo para copiar los datos de DTO, con un cierto 'comportamiento' (por ejemplo, atributo) añadido.

Aunque no está directamente relacionado con la pregunta. 'ViewModel Façade' (viewmodel dentro de otro viewmodel) & 'command' mencionado en esto debe mirar channel 9 link también vale la pena explorarlo (@ 11: 48 comienza)

Cuestiones relacionadas