2009-01-05 12 views
8

Actualmente estoy jugando con el framework Asp.Net mvc y me encanta comparado con el clásico estilo asp.net. Una cosa que estoy discutiendo es si es o no aceptable que una Vista cause (indirectamente) acceso a la base de datos.ASP.Net Mvc - ¿Es aceptable que la Vista llame a funciones que pueden provocar la recuperación de datos?

Por ejemplo, estoy usando el controlador para completar una clase de datos personalizada con toda la información que creo que la vista necesita para hacer su trabajo, sin embargo, como paso objetos a la vista también puede causar lecturas de base de datos.

Un pseudo ejemplo rápido.

public interface IProduct 
{ 
    /* Some Members */ 

    /* Some Methods */ 
    decimal GetDiscount(); 
} 

public class Product : IProduct 
{ 
    public decimal GetDiscount(){ ... /* causes database access */ } 
} 

Si la vista tiene acceso a la clase de producto (que se pasa un objeto IProducto), se puede llamar GetDiscount() y acceso a la base de datos causa.

Estoy pensando en maneras de evitar esto. Actualmente, solo estoy obteniendo herencia de interfaz múltiple para la clase Product. En lugar de implementar solo IProduct, ahora implementaría IProduct y . IProductView enumeraría los miembros de la clase, IProduct contendría las llamadas al método que podrían causar acceso a la base de datos.

La 'Ver' solo conocerá la interfaz en la clase y no podrá llamar a los métodos que provocan el acceso a los datos.

Tengo otros pensamientos vagos acerca de "bloquear" un objeto antes de que se pase a la vista, pero puedo prever un gran alcance para los efectos secundarios con dicho método.

lo tanto, mi pregunta:

  • ¿Hay algún mejores prácticas con respecto a este tema?
  • ¿Cómo otras personas que usan MVC detienen la Vista y hacen más cosas de lo que deberían?

Respuesta

3

Su vista realmente no está causando el acceso a los datos. La vista simplemente llama al método GetDiscount() en una interfaz de modelo. Es el modelo que está causando el acceso a los datos. De hecho, podría crear otra implementación de IProduct que no causaría acceso a datos, sin embargo, no habría ningún cambio en la vista.

Los objetos de modelo que realizan cargas diferidas invariablemente causan acceso a datos cuando la vista intenta extraer datos para su visualización.

Si está bien depende de gusto y preferencia personal.

Sin embargo, a menos que tenga un buen motivo para la carga diferida, preferiría cargar los datos en el objeto modelo y luego pasar ese "preparado" para que se muestre la vista.

+0

Quiero proporcionar datos precocinados listos para la vista, eso es lo que estoy haciendo en el controlador (uso constructores para crear mis clases de modelos de vista), yo (quizás prematuramente) quiero atender situaciones en el futuro en las que pueda querer todo el acceso a db en una transacción, por ejemplo, no es fácil de controlar en una vista. – Ash

+0

No se requiere servicio de catering para estos datos listos para hornear (lo siento, por el terrible juego de palabras ;-))). Su vista no necesita estar al tanto de nada, solo consume el objeto modelo. Depende del controlador y el modelo negociar transacciones, etc. más adelante si es necesario. –

1

una cosa estoy Mooting es si es o no es aceptable para una vista para causar el acceso (indirectamente) a la base de datos?

A menudo hago la misma pregunta. Tantas cosas a las que accedemos en el Modelo en Vistas de desbordamiento de pila pueden causar acceso implícito a la base de datos. Es casi inevitable. Me encantaría escuchar los pensamientos de otros sobre esto.

+1

El modelo en MVC no es el poderoso modelo de dominio. O al menos no debería ser. Es un modelo de vista ligero: una jerarquía de DTO aplanados y seguros para nulos y otros objetos de presentación. Sus controladores y otros servicios crean el modelo de vista; la vista simplemente lo renderiza. –

0

El modelo no debe tener métodos ("acciones") que consistan en acceso a datos. Esa es la preocupación del DAL. Podría tener una propiedad de porcentaje de descuento almacenada en la clase de producto y hacer que el método GetDiscount devuelva un cálculo simple como Price * (100 - discountPercent) o algo como esto.

Desconecto mis entidades comerciales (Producto en su ejemplo) del acceso a los datos. Esa es la preocupación del repositorio (en mi caso).

+0

Tengo métodos en mi Modelo para evitar la situación en la que innecesariamente realiza acciones costosas en la base de datos simplemente para 'poblar' su objeto antes de permitir que otro código lo toque. ¿Qué pasa si en esta circunstancia particular nunca usas el valor de descuento pero aún lo recuperas? – Ash

+0

Probablemente también debería agregar que GetDiscount() es probablemente una mala elección del nombre del método, tal vez GetCategories() podría haber sido más adecuado. Es decir. algo directamente relacionado con el objeto que la clase representa, pero que no forma parte físicamente de la tabla de la base de datos. – Ash

+0

@Ash: para el ejemplo de GetCategories(), habría llenado mi ViewData con un objeto MenuDocument que contenía toda la información necesaria para representar un menú de categorías. El propio MenuDocument podría ser llenado por las clases de dominio de estilo ActiveRecord. –

1

Si mantiene sus objetos de dominio "persistentes ignorantes", entonces no tiene este problema. Es decir, en lugar de tener getDiscount dentro de su clase de Producto, ¿por qué no simplemente tener una propiedad simple llamada Descuento? Esto sería entonces establecido por su ORM cuando cargue la instancia de la clase Product de la base de datos.

+0

Exactamente lo que propuse unos minutos antes ... –

+0

Incluso con POCO, los objetos del modelo PI, la iteración y otras operaciones en ellos pueden causar efectos secundarios. Tenga cuidado al usar el modelo de dominio como un modelo de vista. –

0

He creado un sitio en MonoRail antes de que a veces tenga métodos que activen el acceso a datos desde la vista. Intento evitarlo porque, cuando falla, puede fallar de formas inusuales y no corregibles (en realidad no puedo probar/atrapar en una plantilla de NVELocity, por ejemplo). No es el fin del mundo. Escribí sitios PHP bien abstraídos durante años que accedieron a la base de datos desde la vista y todavía funcionan bastante bien porque la mayoría de las veces si algo explota, estás redirigiendo a un " Algo no funcionó "-type error page de todos modos.

Pero sí, trato de evitarlo. En un sentido más amplio, mi modelo de dominio generalmente no baja hasta la vista. En su lugar, la vista está representando Document objetos que son simplemente volcados de datos de tipo fuertemente descarado, con todo preformateado, batido, triturado y purgado hasta el punto en que la vista solo tiene que escupir algunas cadenas con algunos bucles y si/else, transforma el número "4" en imágenes de 4 estrellas, etc. Este documento generalmente es devuelto por un servicio web que se encuentra frente al modelo de dominio hermoso, o simplemente es una estructura simple que se construye en el controlador y se transfiere como parte del ViewData. Si un objeto de dominio se usa directamente, generalmente no hace nada para activar explícitamente el acceso a los datos; eso es manejado por un repositorio similar a una colección al que la vista no tiene acceso y los objetos de dominio generalmente tampoco tienen acceso.

Pero no tienes que hacerlo de esa manera. Simplemente podría tener la discresión suficiente como para no llamar a los métodos que tocan la base de datos desde la vista.

+0

Estoy haciendo un híbrido en esto, pero tengo una serie de métodos de visualización de ayuda que pueden formatear datos en función del contenido de los objetos suministrados, así que realmente no quiero aplanar/formatear mis datos en el controlador - I ¡Sienta que ese es el trabajo de la vista! – Ash

+0

@Ash: Evaluación bastante justa; de nuevo, mucho de esto es gusto personal. El objeto Documento generalmente * se compila * en sí mismo en función del modelo de dominio, pero ese objeto se instancia/construye en el controlador. Para una arquitectura web, encuentro que los controladores inevitablemente hacen tal interpretación para la vista. –

+0

Esto se está acercando a un modelo de vista mejor. Siempre que este enfoque sea fácilmente comprobable, parece estar bien. –

Cuestiones relacionadas