Estrictamente hablando, un Repositorio ofrece una semántica de recopilación para obtener/poner objetos de dominio. Proporciona una abstracción alrededor de su implementación de materialización (ORM, laminado a mano, simulacro) para que los consumidores de los objetos de dominio se desacoplen de esos detalles. En la práctica, un Repositorio normalmente abstrae el acceso a las entidades, es decir, objetos de dominio con identidad, y generalmente un ciclo de vida persistente (en el sabor DDD, un Repositorio proporciona acceso a Raíces agregadas).
Una interfaz mínima para un repositorio es el siguiente:
void Add(T entity);
void Remove(T entity);
T GetById(object id);
IEnumerable<T> Find(Specification spec);
Aunque verá diferencias de nomenclatura y la adición de Guardar/saveOrUpdate semántica, lo anterior es la idea 'puro'. Obtendrá los miembros Agregar/Eliminar ICollection más algunos buscadores.Si no se utiliza IQueryable, también verá métodos de búsqueda en el repositorio como:
FindCustomersHavingOrders();
FindCustomersHavingPremiumStatus();
Hay dos problemas relacionados con el uso de IQueryable en este contexto. El primero es el potencial para filtrar detalles de implementación al cliente en forma de las relaciones del objeto de dominio, es decir, violaciones de la Ley de Demeter. El segundo es que el repositorio adquiere la búsqueda de responsabilidades que pueden no pertenecer al repositorio de objetos de dominio propiamente dicho, por ejemplo, encontrar proyecciones que son menos sobre el objeto de dominio solicitado que los datos relacionados.
Además, utilizando IQueryable 'rompe' el patrón: Un repositorio con IQueryable puede o no proporcionar acceso a 'objetos de dominio'. IQueryable brinda al cliente muchas opciones sobre lo que se materializará cuando la consulta se ejecute finalmente. Este es el objetivo principal del debate sobre el uso de IQueryable.
En cuanto a los valores escalares, no debe utilizar un repositorio para devolver valores escalares. Si necesita un escalar, normalmente obtendrá esto de la entidad misma. Si esto suena ineficiente, lo es, pero es posible que no lo note, dependiendo de sus características/requisitos de carga. En los casos en que necesita vistas alternativas de un objeto de dominio, por razones de rendimiento o porque necesita fusionar datos de muchos objetos de dominio, tiene dos opciones.
1) Utilice el repositorio de la entidad para buscar las entidades y el proyecto/mapa especificados en una vista aplanada.
2) Cree una interfaz de buscador dedicada a devolver un nuevo tipo de dominio que encapsula la vista aplanada que necesita. Esto no sería un Repositorio porque no habría semántica de Colección, pero podría usar los repositorios existentes debajo de las cubiertas.
Una cosa a considerar si utiliza un repositorio "puro" para acceder a entidades persistentes es que compromete algunos de los beneficios de un ORM. En una implementación 'pura', el cliente no puede proporcionar el contexto de cómo se usará el objeto de dominio, por lo que no puede decirle al repositorio: 'hey, voy a cambiar la propiedad customer.Name, así que don No te molestes en obtener esas referencias cargadas de entusiasmo. Por otro lado, la pregunta es si un cliente debe saber sobre eso. Es una espada de doble filo.
En cuanto al uso de IQueryable, la mayoría de la gente parece sentirse cómoda con 'romper' el patrón para obtener los beneficios de la composición dinámica de consultas, especialmente para las responsabilidades del cliente, como paginación/clasificación. En este caso, es posible que tenga:
Add(T entity);
Remove(T entity);
T GetById(object id);
IQueryable<T> Find();
y, a continuación, puede acabar con todas esas Los métodos de búsqueda personalizados, lo que realmente estorban el Repositorio medida que crecen sus necesidades de consulta.
Me encontré con la publicación de jbogard sobre este tema hoy: http://www.lostechies.com/blogs/jimmy_bogard/archive/2009/09/02/ddd-repository-implementation-patterns.aspx – pfries
+1: ". ..la mayoría de las personas parecen sentirse cómodas con 'romper' el patrón para obtener los beneficios de la composición dinámica de la consulta ... " –