none
ASP .NET MVC 3 & EF - ¿Validaciones en capa de servicios y Data Annotations a la vez? RRS feed

  • Pregunta

  • Buenas noches gente!

    Me ha surgido una duda a la hora de construir la arquitectura de mi aplicación ASP .NET MVC 3:

    Tengo dos proyectos creados, uno que actúa como DAL atacando a un modelo de Entity Framework y otro que es propiamente la apliación MVC. En este proyecto he creado una estructura de controlador-servicio-repositorio. He pensado implementar las validaciones básicas (por ejemplo campos requeridos, longitud máxima de campos tipo string) con Data Annotations sobre unas clases que actúan como modelos para las vistas (serán prácticamente DTOs con los mismos campos de las entidades EF) y las validaciones de negocio en la capa de los servicios. Un ejemplo de validación de negocio sería para mí una validación que obligatoriamente tiene que consultar la base de datos (por ejemplo restricción única de una clave primaria de una entidad)...

    La verdadera duda la tengo en si es correcta esta arquitectura que he montado, ya que en la mayoría de documentación que he buscado o bien atacan directamente al proyecto EF sin capa de servicios (mediante clases partial de las entidades) o hacen todas las validaciones en dicha capa manualmente...He montado así el proyecto porque me parecía la forma más limpia y metódica de implementar las validaciones y encima creo que la aplicación se queda bastante desacoplada para el día de mañana si quiero independizar en un Web Service la capa de servicios o utilizar inyeccion de dependencias, AutoMapper, etc.

    Otra cosa... Creéis que debo montar el clásico UnitOfWork para tener una única instancia del modelo de Entity Framework? Lo digo porque tal como lo he montado, cada repositorio tendría una instancia de éste, aunque he implementado el método Dispose en cada uno de ellos...como lo véis?

    Muchas gracias y perdón por la parrafada!! :-)


    viernes, 14 de septiembre de 2012 21:46

Respuestas

  • Pienso que lo que has montado está bien, pero que tal vez en muchos casos sea "matar moscas a cañonazos". Y me explico: aunque en teoría es buena idea montar una capa de servicios que se interponga entre la capa de datos y la interfaz de usuario (la aplicación mvc), en la práctica es común encontrarse con que un porcentaje muy alto de las clases no tienen ninguna validación en la capa de servicios. Es decir, muy pocos objetos realmente tienen una validación que requiera consultar en base de datos, como tú mencionas. La mayor parte son "transparentes" y simplemente trasladan los mismos campos de la capa de datos sin hacer nada con ellos. Al final se lleva mucho esfuerzo construir y mantener estas clases para que, total, "no hagan nada". Si únicamente las vas a usar para añadir DataAnnotations para forzar a que se hagan validaciones en lado cliente, para eso es preferible omitir la capa de servicios y dejar que la capa cliente se hable directamente con las clases de EF (y meterles las anotaciones mediante clases parciales). Desde luego, en los casos excepcionales en los que sí existan validaciones de negocio, entonces sí que es bueno interponer la capa de servicios, y esa capa llevaría DataAnnotations sobre las propiedaeds que lo requieran.

    En cuanto a las múltiles instancias del ObjectContext, no vale la pena que te preocupes. El Dispose funciona perfectamente, y devuelve al Pool la conexión de base de datos, de forma que la siguiente vez que se construye un ObjectContext éste recupera del Pool la conexión. Esta operación es muy rápida, por lo que no notarás en la práctica ninguna pérdida de rendimiento (ni exceso de conexiones al servidor de base de datos) por este concepto. Es más, en una aplicación web, que lógicamente es multihilo, si tuvieses una única instancia del ObjectContext para todos los hilos podrías tener problemas de concurrencia al tratar de usar todos ellos la misma conexión. Aunque en teoría debería funcionar porque la conexión por defecto lleva en el web.config el MARS activado, yo personalmente no me atrevería a depender del MARS para un sistema de alta concurrencia como es una aplicación web.

    • Marcado como respuesta Iván Reinoso lunes, 17 de septiembre de 2012 13:05
    lunes, 17 de septiembre de 2012 12:04

Todas las respuestas

  • Pienso que lo que has montado está bien, pero que tal vez en muchos casos sea "matar moscas a cañonazos". Y me explico: aunque en teoría es buena idea montar una capa de servicios que se interponga entre la capa de datos y la interfaz de usuario (la aplicación mvc), en la práctica es común encontrarse con que un porcentaje muy alto de las clases no tienen ninguna validación en la capa de servicios. Es decir, muy pocos objetos realmente tienen una validación que requiera consultar en base de datos, como tú mencionas. La mayor parte son "transparentes" y simplemente trasladan los mismos campos de la capa de datos sin hacer nada con ellos. Al final se lleva mucho esfuerzo construir y mantener estas clases para que, total, "no hagan nada". Si únicamente las vas a usar para añadir DataAnnotations para forzar a que se hagan validaciones en lado cliente, para eso es preferible omitir la capa de servicios y dejar que la capa cliente se hable directamente con las clases de EF (y meterles las anotaciones mediante clases parciales). Desde luego, en los casos excepcionales en los que sí existan validaciones de negocio, entonces sí que es bueno interponer la capa de servicios, y esa capa llevaría DataAnnotations sobre las propiedaeds que lo requieran.

    En cuanto a las múltiles instancias del ObjectContext, no vale la pena que te preocupes. El Dispose funciona perfectamente, y devuelve al Pool la conexión de base de datos, de forma que la siguiente vez que se construye un ObjectContext éste recupera del Pool la conexión. Esta operación es muy rápida, por lo que no notarás en la práctica ninguna pérdida de rendimiento (ni exceso de conexiones al servidor de base de datos) por este concepto. Es más, en una aplicación web, que lógicamente es multihilo, si tuvieses una única instancia del ObjectContext para todos los hilos podrías tener problemas de concurrencia al tratar de usar todos ellos la misma conexión. Aunque en teoría debería funcionar porque la conexión por defecto lleva en el web.config el MARS activado, yo personalmente no me atrevería a depender del MARS para un sistema de alta concurrencia como es una aplicación web.

    • Marcado como respuesta Iván Reinoso lunes, 17 de septiembre de 2012 13:05
    lunes, 17 de septiembre de 2012 12:04
  • Muchas gracias Alberto, es la respuesta que necesitaba. Lo que comentas es justo lo que me dio por pensar ayer, aunque tampoco está mal dejar la capa de servicios montada y funcionando, puesto que de momento no sé si se va a presentar alguna validación de las que he considerado "de negocio", ¿no crees?

    Un saludo.

    lunes, 17 de septiembre de 2012 13:07