Para los controladores y ViewModels, que debe contener la mayor parte de la lógica de negocio?
Ninguno de esos.
He intentado de varias maneras hacer que mis ViewModels prácticamente contengan toda la lógica comercial. Sin embargo, tengo que tener un argumento en el constructor de mi ViewModel que tome una unidad de trabajo. ¿Es esta una buena idea?
imho Es una muy mala idea. En primer lugar, está rompiendo varios de los principios SÓLIDOS. Agrupar todo el código en el modelo de vista hace que sea difícil probarlo. ¿Qué sucede si desea usar parte de la lógica comercial en otra vista? ¿Duplicas ese código?
¿Cuál es la mejor práctica aquí?
Regresemos primero al patrón MVC. Es una definición bastante amplia, pero sabiendo que debería darle una sensación de lo que debe colocar donde.
El "Modelo" en MVC es realmente todo lo que se utiliza para juntar los datos. Puede ser servicios web, una capa empresarial, repositorios, etc.
La vista es todo el código que genera el HTML (ya que estamos hablando de web).
El controlador debe considerarse como un pegamento entre el modelo y la vista. Por lo tanto, debe tomar la información del Modelo y transformarla en algo utilizable por la vista.
El problema con esa estructura es que es bastante fácil "filtrar" información específica de la capa en las otras partes del patrón. De ahí que Microsoft introdujo ViewModels en su implementación de MVC.
De esta manera, podemos eliminar toda la lógica de representación de las vistas y ponerla en el modelo de vista. En vez de hacer esto en su vista:
<span>@(model.Age == 0 ? "n/a" : model.Age)</span>
pones ese código dentro del modelo de vista en su lugar y sólo tiene que llamar @model.Age
. De esta forma, no tiene que duplicar ese código en todas las vistas que usan su modelo de vista.
La respuesta a su pregunta sobre el ViewModel es que solo debe contener la lógica que se utiliza para representar la información del "Modelo" correctamente.
En cuanto al controlador, tampoco pondría ninguna lógica comercial en él. Antes que nada, hace que sea muy difícil probar tu lógica. Luego le agrega más responsabilidades (y al hacerlo, rompe el SRP). La única lógica que es válida en el controlador es tomar la información del ViewModel y transformarla en algo utilizable por el "Modelo" y viceversa.
Espero que responda a su pregunta.
actualización
me gustaría crear un proyecto separado y añadir clases a la misma. Luego solo agrega una referencia de tu proyecto web y llama a esas clases en los controladores.
También comenzaría a usar un contenedor de inversión de control para obtener automáticamente las dependencias creadas para mí.
Autofac pueden descubrir sus servicios por usted (cero-configuración) e insertarse en MVC.
seguir el modelo de interfaz separados crean los siguientes proyectos:
- YourProject.BusinessLayer < - Añada sus clases aquí
- YourProject.BusinessLayer.Specification < - Añadir que las interfaces que define su capa de negocio aquí.
- YourProject.Mvc < - El proyecto MVC.
El proyecto "Especificación" se puede utilizar para facilitar la prueba de cosas y facilitar el cambio de implementación (pueden ser solo unas pocas clases y no necesariamente toda la capa empresarial). Lea en "Patrón de interfaz separada"
Buena respuesta. Me gustaría preguntar dónde iría mi lógica comercial. – TIHan
Lee mi actualización. – jgauffin
Gracias. Comenzaré a investigar esto. – TIHan