work unit pattern net mvc generic framework example driven domain c# .net domain-driven-design repository-pattern ddd-repositories

unit - repository pattern c# mvc



DDD-Cómo implementar repositorios de alto rendimiento para la búsqueda (2)

Tengo una pregunta sobre la DDD y el patrón de repositorio.

Digamos que tengo un repositorio de Clientes para la raíz agregada de Clientes. Los métodos Get & Find devuelven el agregado completo, que incluye objetos como Dirección, etc. Todo bien. Pero cuando el usuario está buscando un cliente en la interfaz de usuario, solo necesito un "resumen" del agregado, solo un objeto plano con información resumida.

Una forma en que podría lidiar con esto es llamar al método de búsqueda en el repositorio como de costumbre, y luego en la capa de aplicación, asignar cada agregado de cliente a un DTO de Búsqueda de Cliente / Información de Cliente, y enviarlos de vuelta al cliente.

Pero mi problema con esto es el rendimiento; cada agregado de Cliente puede requerir múltiples consultas para completar todas las asociaciones. Entonces, si mis criterios de búsqueda coincidían con 50 clientes, ese es un gran éxito en la base de datos para poder recuperar datos que ni siquiera voy a necesitar.

El otro problema es que es posible que desee incluir datos resumidos sobre el cliente que están fuera del límite de la raíz agregada del Cliente, como la fecha del último pedido realizado, por ejemplo. La orden tiene su propio agregado y, por lo tanto, para obtener la información de la orden del cliente, tendría que llamar a OrderRepository, lo que también degradaría el rendimiento.

Así que ahora creo que me quedan dos opciones:

  1. Agregue un método de búsqueda adicional al CustomerRepository que devuelve una lista de estos objetos de resumen haciendo una consulta eficiente.

  2. Cree un CustomerInfoRepository de solo lectura creado para tal fin, que solo tenga el método de búsqueda descrito en 1.

Pero ambos sienten que voy en contra de los principios de la DDD. Mis repositorios heredan de una base genérica: Repositorio donde T: IAggregateRoot. Estos objetos de información de resumen no son agregados, y son de un tipo diferente a T, por lo que realmente el # 1 va en contra del diseño.

Tal vez para el # 2 crearía un SearchRepository abstracto sin la restricción IAggregateRoot?

Hay muchos escenarios similares en mi dominio.

¿Cómo implementarías este escenario?

Gracias Dave

Actualizar

Después de leer la respuesta de Theo, creo que iré con la opción # 2 y crearé un SearchRepository especializado dentro de mi infraestructura orientado a estos escenarios. La capa de aplicación (servicios WCF) puede llamar a estos repositorios que simplemente rellenan los DTO de resumen directamente en lugar de asignar entidades de dominio a los DTO.

**** Actualización 2 ****

Aunque pregunté esto hace más de un año, pensé que solo agregaría que desde entonces he descubierto el CQRS que tiene como objetivo resolver este problema exacto. Udi Dahan ( http://www.udidahan.com/ ) y Greg Young ( http://codebetter.com/gregyoung/ ) han escrito mucho sobre esto. Si está creando una aplicación distribuida con DDD, ¡CQRS es para usted!


Creo que solo quieres mostrar información resumida. Estos bits de información resumida no son entidades u objetos de valor del modelo de dominio. Son solo información, nada más.

Es algo así como mostrar información de informes. Si trato con esas cosas, no me atendré al enfoque DDD puro. Sus opciones sugeridas están bien, porque está haciendo su trabajo. DDD no debe ser tratado como dogma. Pensar fuera de la caja. Aflojar un poco DDD.

Pero tenga en cuenta que solo está creando valores informativos fuera del modelo para fines de visualización. Entonces, si un usuario selecciona un bit de información para realizar alguna operación con él (que se define en el modelo de dominio), debe extraer el identificador de los valores informativos y extraer la entidad / valor objeto / agregado de un repositorio.

Recomiendo este video: Eric Evans: Lo que he aprendido sobre la DDD desde el libro . Si lees su libro, deberías ver el video completo. Preste mucha atención aproximadamente a las 30:00, hora en que el propio Eric Evans habla sobre los agregados y se refiere al problema que tiene actualmente.


Me gustaría:

  1. Devuelve un objeto diferente que representa una vista de mi objeto para su visualización, por ejemplo, CustomerInfo.
  2. Devuelve un DataTable. A menudo, un contenedor genérico es la forma más fácil y mejor de ir.

Si la T en su repositorio genérico es un Cliente, creo que está aplicando incorrectamente el concepto de raíces agregadas, aunque no soy un Evansangelist . Diseñaría un repositorio para el Cliente que devolviera los datos que se agrupan lógica o cómodamente con el Cliente, incluidas las Tablas de datos u objetos de solo lectura que son vistas de los datos del Cliente.