DDD - Como implementar repositórios de alto desempenho para pesquisa
Eu tenho uma pergunta sobre DDD e o padrão do repositório.
Digamos que eu tenha um repositório do cliente para a raiz agregada do cliente. Os métodos Get & Find retornam o agregado totalmente preenchido, que inclui objetos como Endereço, etc. Tudo bem. Mas quando o usuário está procurando um cliente na interface do usuário, eu apenas exijo um 'resumo' do agregado - apenas um objeto simples com informações resumidas.
Uma maneira de lidar com isso é chamar o método find no repositório como normal e, em seguida, na camada de aplicativo, mapear cada cliente agregado para um DTO CustomerSearchResult / CustomerInfo e enviá-lo de volta ao cliente.
Mas meu problema com isso é desempenho; cada agregado do Cliente pode exigir várias consultas para preencher todas as associações. Portanto, se meus critérios de pesquisa corresponderem a 50 clientes, é um grande sucesso no banco de dados por recuperar potencialmente dados de que não vou precisar.
A outra questão é que talvez eu queira incluir dados resumidos sobre o cliente que estejam fora do limite raiz agregado do Cliente, como a data do último pedido feito, por exemplo. O pedido possui agregação própria e, portanto, para obter as informações do pedido do cliente, eu precisaria chamar o OrderRepository, também prejudicando o desempenho.
Então agora eu acho que tenho duas opções:
Adicione um método Find adicional ao CustomerRepository que retorne uma lista desses objetos de resumo fazendo uma consulta eficiente.
Crie um propósito criado somente para leitura CustomerInfoRepository, que possua apenas o método find descrito em 1.
Mas ambos parecem estar indo contra os princípios do DDD. Meus repositórios herdam de uma base genérica: Repository em que T: IAggregateRoot. Esses objetos de informações resumidas não são agregados e são de um tipo diferente de T; portanto, o número 1 realmente é contrário ao design.
Talvez para o número 2 eu crie um SearchRepository abstrato sem a restrição IAggregateRoot?
Existem muitos cenários semelhantes no meu domínio.
Como você implementaria esse cenário?
Obrigado Dave
Atualizar
Depois de ler a resposta de Theo, acho que vou usar a opção 2 e criar um SearchRepository especializado dentro da minha infraestrutura voltada para esses cenários. A camada de aplicativo (serviços WCF) pode chamar esses repositórios que apenas preenchem os DTOs de resumo diretamente, em vez de mapear entidades de domínio para DTOs.
**** Atualização 2 ****
Embora eu tenha perguntado isso há mais de um ano, pensei em acrescentar que, desde então, descobri o CQRS, que visa solucionar esse problema exato. Udi Dahan (http://www.udidahan.com/) e Greg Young (http://codebetter.com/gregyoung/) escreveram muito sobre isso. Se você estiver criando um aplicativo distribuído com DDD, o CQRS é para você!