Pessoal,
Já faz um tempo que eu estava me cobrando enviar esta dúvida aqui.
Eu tenho o costume de fazer a camada de acesso a dados baseada em RoleInterfaces. Assim:
Num sistema, por exemplo, de automação de força de vendas pra indústria farmacêutica, os representantes visitam médicos e farmácias.
Em alguns casos eu só quero trabalhar com médicos, outros só com farmácias, outros com ambos. Ainda em outros casos, o laboratório tem produtos segmentados para ortodontia ou oftamologia e, apesar do oftamologista também ser médico, ele quer que seja tratado como um cara separado em alguns aspectos e em outros como um igual entre médicos e farmácias.
A minha solução pra isso pode não ser a melhor de todas, mas atendeu bem:
Eu criei uma tabela Master com todos os meus objetos estáticos contendo Id e Nome e ela era a base para as composições com relacionamento 1 para 1 com outras tabelas. As tabelas Medicos e Farmacias, por exemplo, complementavam a tabela Master, mas a tabela Oftamologistas complementava a tabela Medicos, montando assim um esquema bastante flexível. A tabela Visitáveis (um nome horrível, mas nunca encotramos um melhor) tornava todos estes ítens comuns entre eles com os dados de visitas (endereço e agendamento, além de identificar que representante seria responsável pela visita).
Para atender este modelo, invés de criarmos repositórios de objetos, criamos RoleInterfaces (IMaster, IMedico, IFarmacia, IOftamologista, IVisitavel) e fizemos com que as entidades fôssem na verdade um agrupamento de interfaces, um Repositório Master servia para todas as entidades, e criava um Repositório para cada tabela, baseado na interface dela. O método Salvar, por exemplo, do repositório Master, recebia objeto de qualquer entidade, instanciava os repositórios e invocava o método Salvar de cada um deles enviando o objeto recebido e estes avaliavam o compatibilidade do objeto com a interface em que eram baseados pra fazer ou não o update na tabela). Já a seleção dos dados era feita enviando ao Repositório Master uma flag de contexto ("Oftamologistas" por exemplo) que identificava o repositório base e o instanciava, este conhecendo seu contexto, fazia os joins necessários (Médicos e Master) ou, no caso de um repositório composto, como Visitáveis, instanciava os outros repositórios, fazia a seleção em cada um deles e devolvia uma lista com o Merge do resultado. Com o tempo otimizamos tudo com lazy loading em alguns pontos, e os repositórios compostos passaram a fazer as seleções em threads separadas e o merge acontecia depois de fazer um join nas threads.
Bom, descrito como eu monto meu acesso a dados, alguém aqui saberia me dizer se transpor isso para um ORM é possível sem ferir este modelo? Não conheço o NHibernate mas eu vi que o EF não baseia seus containers em interfaces. Alguém saberia me dizer uma forma de fazê-lo? De preferência, de uma forma que suporte LINQ (já que, o objetivo verdadeiro é este).
Opiniões a respeito desta forma de montar o acesso a dados também serão bem vindas: positivas e negativas.
Atenciosamente,
Daniel Moreira Yokoyama.
http://halonfullestuse.wordpress.com/"I am putting myself to the fullest possible use, which is all I think that any conscious entity can ever hope to do."
(HAL 9000)