2010-09-23 10 views
6

Estoy estudiando MVC y EF por el momento y veo con bastante frecuencia en los artículos sobre esos temas que el controlador manipula los datos a través de un objeto Repositorio en lugar de usar directamente LINQ para Entidades.¿Es realmente necesario implementar un Repositorio cuando se usa Entity Framework?

Creé una pequeña aplicación web para probar algunas ideas. Se declara la siguiente interfaz como una abstracción del almacenamiento de datos

public interface ITinyShopDataService 
{ 
    IQueryable<Category> Categories { get; } 
    IQueryable<Product> Products { get; } 
} 

Entonces tengo una clase que hereda de la clase generada TinyShopDataContext (heredado de ObjectContext) e implementa ITinyShopDataService.

public class TinyShopDataService : TinyShopDataContext, ITinyShopDataService 
{ 
    public new IQueryable<Product> Products 
    { 
     get { return base.Products; } 
    } 

    public new IQueryable<Category> Categories 
    { 
     get { return base.Categories; } 
    } 
} 

Finalmente, un controlador utiliza una implementación de ITinyShopDataService para obtener los datos, p. para mostrar productos de una categoría específica.

public class HomeController : Controller 
{ 
    private ITinyShopDataService _dataService; 

    public HomeController(ITinyShopDataService dataService) 
    { 
     _dataService = dataService; 
    } 

    public ViewResult ProductList(int categoryId) 
    { 
     var category = _dataService.Categories.First(c => c.Id == categoryId); 
     var products = category.Products.ToList(); 
     return View(products); 
    } 
} 

Creo que el controlador anterior posee algunas propiedades positivas.

  • Es fácilmente comprobable debido a que se está inyectando el servicio de datos.
  • Utiliza sentencias LINQ que consultan un almacenamiento de datos abstracto de forma neutral para la implementación.

Por lo tanto, no veo ningún beneficio de agregar un repositorio entre el controlador y la clase ObjectContext-derived. ¿Qué extraño? (Lo siento, fue un poco demasiado largo para la primera publicación)

Respuesta

5

Puede probar sus controladores muy bien con lo que propone.

Pero, ¿cómo se puede comprobar sus consultas dentro del servicio de datos? Imagine que tiene un comportamiento de consulta muy complicado, con múltiples consultas complejas para devolver un resultado (verificar la seguridad, consultar un servicio web, consultar el EF, etc.).

Puede poner eso en el controlador, pero eso es claramente incorrecto.

Debe ir en su capa de servicio, por supuesto. Puede simular/falsificar la capa de servicio para probar el controlador, pero ahora debe probar la capa de servicio.

Sería bueno si pudiera hacer esto sin conectarse a una base de datos (o servicio web). Y ahí es donde entra en juego el Repositorio.

El servicio de datos puede usar un repositorio "tonto" como una fuente de datos en la que puede realizar consultas complejas.Luego puede probar el servicio de datos reemplazando el repositorio con una implementación falsa que usa un List<T> como su almacén de datos.

Lo único que hace que esto sea confuso es la gran cantidad de ejemplos que muestran los controladores hablando directamente con los repositorios. (Arquitectura S # arp, te estoy mirando.) Si estás viendo esos ejemplos, y ya tienes una capa de servicios, entonces estoy de acuerdo en que es difícil ver cuál es el beneficio del repositorio. Pero si solo considera la prueba de la capa de servicio, y no planea tener controladores hablando directamente con el repositorio, entonces comienza a tener más sentido.

0

Lo que te hace falta es la capacidad de actualizar, crear y eliminar objetos. Si eso no es un problema, entonces la interfaz probablemente sea lo suficientemente buena (aunque dejaría que se derivara de IDisposable para asegurarse de que siempre se puede eliminar el contexto (y probar esto))

+0

Ok, lo despojó de todo lo que no sea esencial y sólo la dejó líneas que ilustran la idea de que, si hubiera creado un Repositorio, habría consistido únicamente en métodos de una o dos líneas que casi no hubieran agregado ningún valor apreciable. –

+0

Ah, ahora veo lo que dices ... Estás extrayendo una interfaz de DBContext, en lugar de usar un repositorio para envolverlo. –

2

Ayende del proyecto NHibernate y otra fama agrees with you.

Algunas personas de Diseño impulsado por el dominio sugerirían que debe tener un servicio (no el mismo servicio web) capa que se llama desde su controlador, pero DDD generalmente se aplica a dominios complejos. En aplicaciones simples, lo que estás haciendo está bien y es comprobable.

0

El patrón de repositorio no tiene nada que ver con Entity Framework, aunque Entity Framework implementa un patrón de "repositorio". La interfaz del repositorio (digamos IRepositoryProducts) vive en la capa de dominio. Comprende los objetos de dominio, o incluso las entidades, si no desea utilizar el diseño impulsado por el dominio.

Pero su aplicación (digamos RepositoryProducts) es la implementación real patrón de repositorio y no vive en la capa de dominio, pero en la capa de persistencia .

Esta implementación puede usar Entity o cualquier ORM ..o no para conservar la información en la base de datos.

Así que la respuesta es: no es realmente necesario, pero se recomienda utilizar el patrón Repository a pesar de utilizar Entity ORM como una buena práctica para mantener la separación entre la capa de dominio y la capa de persistencia. Porque ese es el propósito del patrón de repositorio: separación de preocupaciones entre la lógica del dominio y la forma en que persiste la información. Al usar el patrón de repositorio desde el nivel del dominio, simplemente se abstrae y piensa: "Quiero almacenar esta información, no me importa cómo se hace", o "Quiero una lista de estas cosas, no me importa dónde los obtienes o cómo los recuperas. Solo dénmelos ".

Entity Framework no tiene nada que ver con la capa de dominio, que es sólo una buena manera de persistencia de objetos, pero debe vivir en la implementación de repositorios (capa de persistencia)

Cuestiones relacionadas