Generalmente, si utiliza un patrón de repositorio "verdadero", a diferencia de otras capas de persistencia (por ejemplo, ActiveRecord o DAO), debe intentar identificar los agregados de su dominio y crear un repositorio por agregado.
¿Qué significa eso? Bueno, depende mucho de su aplicación, pero en general hay objetos que son naturalmente 'padres' de otros objetos, o que son parte de una transacción relacionada.
Creo que el ejemplo canónico es un sistema de comercio electrónico en el que tiene un concepto de orden, y en un orden tiene líneas de pedido cada línea de pedido es un producto y una cantidad, y así sucesivamente.
En ese caso, el objeto Order es una de las raíces agregadas del sistema y se crea un OrderRepository.
Lo que hay que recordar en ese caso es que existe alguna relación (implícita o no) entre un pedido y sus líneas de orden, etc. Por lo tanto, las partes C-UD de "CRUD" en el Repositorio generalmente deberían ser solo un método cada una, y generalmente solo deberían tomar una instancia de ese objeto raíz agregado y operar en él (por ejemplo, repo.Save (order)). Otros posibles params podrían estar ahí, pero eso depende de tu impl.
De hecho, a menudo puede resolver la mayoría de la parte C-UD con herencia (es decir, crear una RepositoryBase que los implemente utilizando alguna lógica conocida sobre qué sucederá para su esquema de persistencia particular).
Eso nos deja la parte R de CRUD. En este caso, es posible que obtenga un montón de métodos de consulta (GetById; GetByName; GetByCustomerName, etc.) si elige ir a la ruta del método de consulta. Algunas personas prefieren, especialmente para aplicaciones simples, exponer una interfaz basada en linq (por ejemplo, un GetEll de IQueryable) que puede tener cláusulas WHERE aplicadas.YMMV dependiendo de tu persistencia subyacente en eso, pero es una oportunidad sólida para aplicaciones simples, esp. si espera que su proveedor de persistencia soporte linq directamente.
Por último, muchas personas realmente separan la parte de la consulta a través de una implementación u otra del patrón de separación de responsabilidad de consulta de comando, que dice que las interfaces para persistir y consultar deben ser diferentes. En ese caso, tendrías un Repo que solo tiene operaciones CRUD (GetById, GetAll, Save, Delete) básicas y otra clase de algún tipo que consulta cosas según las intenciones de tu aplicación.
Espero que ayude.
Paul
Paul gracias por la respuesta detallada. Después de mucho pensarlo y leerlo, siento que estás al tanto con un repositorio/servicio por raíz agregada. También tiene razón sobre el CRUD, 1 método cada uno para C_UD y muchos métodos de R. En su ejemplo de Pedido, ¿el OrderRepository también sería el lugar para poner los métodos R para OrderLines y OrderSubLines? – bradjive
Esa es una buena pregunta, y depende. ¿Las líneas de pedido y sublíneas realmente significan algo útil sin su orden asociado? Si es así, entonces sí, si no es así, todas las consultas tienen que ver con Orders y puede filtrar las colecciones secundarias utilizando expresiones LINQ regulares sobre los IEnumerables. – Paul