Al planificar la arquitectura para una aplicación web MVC de mediana y gran escala, ¿cómo implementa las capas para que estén tan desacopladas como sea posible y fáciles de probar? (básicamente siga las mejores prácticas) Digamos que estoy usando el código primero como mi acceso a datos.
Lucho con qué definir como "lógica de negocios" y cómo se supone que interactúa con la capa de datos. Tomando una aplicación de venta de vehículos como ejemplo, ¿sería la lógica de negocios clases que realizaran tareas como calcular la banda de impuestos para vehículos dados, comparar estadísticas de millas por galón, etc.? En cuanto a las entidades comerciales (por ejemplo, automóviles, furgonetas, motocicletas), las incluiría en la capa de datos junto con mi DataContext
clase.
Además, ¿qué constituiría la lógica de la aplicación en lugar de la empresa? Supongo que cosas como validaciones de entrada de sesión / usuario?
Entonces, por ejemplo, un controlador de automóvil podría devolver un resultado de acción / vista que enumera los diez automóviles principales filtrados por tipo y mejor mpg. Entonces, digamos que tengo un ICarRepository
'carRepo' inyectado en mi controlador (usando el patrón de repositorio / DI), filtro mis autos desde un parámetro del método de acción, por ejemplovar cars = carRepo.getCarsByType("hatchback");
Así que mantuve el conocimiento de acceso a datos fuera de mi controlador usando un repositorio, ahora para mantener la lógica de negocios fuera del controlador usando un modelo de dominio - var result = new MpgCalculator (cars); - Digamos que necesito la clase de calculadora porque necesita realizar una lógica adicional para calcular la mejor eficiencia de combustible, más que solo cargar / filtrar entidades del DB. Entonces, ahora tengo un conjunto de datos para mi vista que representa que utilizó un repositorio para recuperar de la capa de acceso a datos y un objeto específico de dominio para procesar y realizar tareas relacionadas con el negocio en esos datos.
¿Estoy cometiendo errores aquí? ¿todavía necesitamos usar el patrón de repositorio o puedo simplemente codificar contra una interfaz para desacoplar el ORM y probar? Sobre este tema, dado que mis clases concretas de acceso a datos dbcontext están en la capa de datos, ¿deberían las definiciones de interfaz entrar en la capa de dominio / negocio, lo que significa que si la tecnología de acceso a datos cambia alguna vez, mis otras capas no se verán afectadas?
Por lo que he estudiado hasta ahora, mi estructura se ve así:
Aplicación de Internet MVC -> El proyecto estándar de Internet - los modelos aquí son ViewModels
Capa de dominio / negocio -> clases / modelos específicos de negocio que los controladores pueden usar para procesar entidades de dominio desde la capa de datos antes de pasar a las vistas relevantes
¿Es necesaria la abstracción del repositorio? -> Escucho mucho debate sobre esto, especialmente cuando uso un ORM
Capa de datos -> Clases de entidad (automóvil, furgoneta, motocicleta), DbContext - Capa de tecnología de acceso a datos concretos
fuente
Parece que todo es correcto para su estructura. Lo único de lo que no estoy seguro es que mencione que los modelos en MVC son "ViewModels" y que sus controladores hablan con la capa de dominio. Creo que esto tiene sentido si su patrón predeterminado es usar el controlador para acceder a la capa de dominio y luego usar sus "ViewModels" como compilaciones de información más específicas de la vista de múltiples entidades de dominio, como tiene sentido para esa vista en particular. Si eso es lo que estás haciendo, entonces es probable que estés bien.
Hay una escuela de pensamiento que debería tener una abstracción completa de su capa de dominio en su aplicación MVC si va a tener alguna. Personalmente, la idea de hacerlo en una aplicación empresarial me causa graves dolores mentales.
Prefiero usar el patrón de repositorio para administrar el acceso a la capa de datos, ya que mejora la capacidad de prueba y la flexibilidad. Las dos cosas que tienden a hacer los cambios más drásticos son la interfaz de usuario y la base de datos. Imagínese si parte de la información que está extrayendo directamente de la base de datos se cambia para que tenga que recuperarse de una llamada de servicio en lugar de una llamada a la base de datos, o parte de la información se transfiere a una base de datos diferente que requiere un .edmx diferente expediente. El patrón de repositorio proporciona abstracción para apoyar esto.
fuente