Repositórios não são DAOs. E também não são um lugar legal para você colocar métodos que você não sabe onde por, só porque eles tem algum contato na infra-estrutura. Para isso existe a camada de infra-estrutura.

No DDD, repositórios representam coleções das entidades do domínio. É simples assim. Repositórios falam a linguagem ubíqua, ou seja, nas suas interfaces, eles não sabem o que é SQL, eles não conhecem contextos do LINQ to SQL, Entity Framework, ou a sessão do NHibernate. É óbvio que internamente eles conhecem esse tipo de coisa, e, ou eles criam suas dependências ou elas são injetadas de alguma forma. Mas suas interfaces não conhecem. Sempre acho uma boa idéia o repositório ser definido como uma interface, que uma classe concreta qualquer vai implementar. Essa classe até pode acrescentar métodos a mais, só que ninguém vai saber que eles existem, porque a classe vai sempre estar por trás de uma abstração, que é a interface. E o ideal mesmo é você definir a interface antes de implementar a classe concreta de repositório, e daí passar para criar o resto da aplicação, trabalhando com uma classe fake por um tempo, ou com um mock. Depois que tiver alguma coisa funcionando, você implementa o acesso aos dados com a tecnologia que escolheu. Isso garante que você não vai fazer nada muito maluco no repositório.

Repositórios também não fazem coisas esdrúxulas, como enviar e-mail, checar configurações do web.config, ou acessar a sessão do ASP.Net. Não fazem.

Se você tem um repositório que envia e-mails você tem um problema. Ele tem duas responsabilidades: ele representa uma coleção de entidades e ele envia mensagens. E não interessa se ele usa um outro objeto para enviar os e-mails, ele ainda está fazendo o trabalho, que na prática é de um coordenador que pode estar na camada da aplicação, ou de um serviço. Lembrando de novo: repositórios são coleções de entidades. Você não espera que uma coleção envie e-mails, não é?

Um repositório que checa configurações de um web.config ou app.config também é um problema. Você está dependendo de um serviço de infra-estrutura, que está na camada de interface com o usuário, para que o repositório possa funcionar. Percebe como o objeto ficou acoplado a vários pontos? Não faça isso, passe o objeto que o repositório precisa para trabalhar, o DAO em si, já configurado para ele, via construtor.

E nem preciso dizer que repositórios não devem em hipótese alguma acessar uma sessão do ASP.Net, porque ele estaria cruzando camadas de forma horrorosa. E se amanhã a aplicação for mobile?

Na .Net 58 fiz um artigo sobre uma aplicação web corporativa, usando conceitos de DDD. Lá eu tinha um repositório de usuários, baseado em profiles e membership do ASP.Net. Foi uma decisão pensada, que efetivamente acoplou o repositório concreto ao ASP.Net, e à configurações do web.config, mas trouxe outros diversos benefícios. Temos que ser pragmáticos, e não fanáticos radicais e puristas ao extremo, e foi o que fiz naquele exemplo. Mas ainda assim, a interface dependia somente das entidades da aplicação, sem ligação ao ASP.Net. Por esse motivo, se eu quisesse trocar de profiles para SQL Server seria extremamente simples.

Giovanni Bassi

Arquiteto e desenvolvedor, agilista, escalador, provocador. É fundador e CSA da Lambda3. Programa porque gosta. Acredita que pessoas autogerenciadas funcionam melhor e por acreditar que heterarquia é mais eficiente que hierarquia. Foi reconhecido Microsoft MVP há mais de dez anos, dos mais de vinte que atua no mercado. Já palestrou sobre .NET, Rust, microsserviços, JavaScript, TypeScript, Ruby, Node.js, Frontend e Backend, Agile, etc, no Brasil, e no exterior. Liderou grupos de usuários em assuntos como arquitetura de software, Docker, e .NET.