Muitos tutoriais sobre DDD que estudei são principalmente sobre teoria. Todos eles têm exemplos de código rudimentares (Pluralsight e similares).
Na web, também existem algumas tentativas de algumas pessoas de criar tutoriais que cobrem DDD com EF. Se você começar a estudá-los apenas brevemente - notará rapidamente que eles diferem muito um do outro. Algumas pessoas recomendam manter o aplicativo mínimo e evitar a introdução de camadas adicionais, por exemplo, repositório no EF , outras estão gerando camadas extras, muitas vezes até violando o SRP ao injetar DbContext
em Raízes Agregadas.
Peço desculpas se estiver fazendo uma pergunta baseada em opinião, mas ...
Quando se trata de prática - o Entity Framework é um dos ORMs mais poderosos e amplamente utilizados. Infelizmente, você não encontrará um curso abrangente cobrindo o DDD.
Aspectos importantes:
O Entity Framework traz UoW e Repository (
DbSet
) fora da caixacom a EF, seus modelos têm propriedades de navegação
com a EF, todos os modelos estão sempre disponíveis desativados
DbContext
(eles são representados como aDbSet
)
Armadilhas:
você não pode garantir que seus modelos filhos sejam afetados apenas pela Raiz agregada - seus modelos têm propriedades de navegação e é possível modificá-los e chamar
dbContext.SaveChanges()
com
DbContext
você, você pode acessar todos os seus modelos, contornando a raiz raiz agregadavocê pode restringir o acesso aos filhos do objeto raiz via
ModelBuilder
noOnModelCreating
método , marcando-os como campos - ainda não acredito que seja o caminho certo para obter DDD, além de ser difícil avaliar que tipo de aventuras isso pode levar no futuro ( bastante cético) )
Conflitos:
sem implementar outra camada de repositório que retorne agregado, não podemos nem mesmo resolver parcialmente as armadilhas acima mencionadas
implementando uma camada extra de repositório, estamos ignorando os recursos internos do EF (todos
DbSet
já são um repositório ) e complicando demais o aplicativo
Minha conclusão:
Perdoe minha ignorância, mas com base nas informações acima - o Entity Framework não é adequado para o Design Orientado a Domínio ou o Design Orientado a Domínio é uma abordagem imperfeita e obsoleta .
Eu suspeito que cada uma das abordagens tem seus méritos, mas agora estou completamente perdida e não tenho a menor idéia de como reconciliar EF com DDD.
Se eu estiver errado - alguém poderia pelo menos detalhar um conjunto simples de instruções (ou até mesmo fornecer exemplos decentes de código) de como proceder com o DDD com a EF, por favor?
Respostas:
DDD e EF têm pouco ou nada a ver um com o outro.
DDD é um conceito de modelagem. Significa pensar no domínio, nos requisitos de negócios e modelá-los. Especialmente no contexto da orientação a objetos, significa criar um design que reflita as funções e os recursos comerciais.
EF é uma tecnologia de persistência. Ele se preocupa principalmente com dados e registros de banco de dados.
Estes dois são fortemente divorciados. Um design DDD pode usar EF de alguma forma sob o capô, mas os dois não devem interagir de nenhuma outra maneira.
Algumas interpretações do Design Orientado a Domínio realmente defendem a modelagem de dados, e acho que é disso que se trata sua pergunta. Nesta interpretação, "Entidades" e "Objetos de Valor" são essencialmente apenas titulares de dados sem função, e o design se preocupa com quais propriedades elas mantêm e qual relação elas têm entre si. Nesse contexto, DDD vs. EF pode surgir.
Essa interpretação, no entanto, é falha, e eu recomendo fortemente ignorá-la por completo.
Concluindo : DDD e EF não são mutuamente exclusivos, eles são irrelevantes um para o outro, desde que você faça modelagem de objeto adequada e não modelagem de dados. Os objetos DDD não devem, de forma alguma, ser artefatos EF. Entidades DDD não devem ser "entidades" EF, por exemplo. Dentro de alguma função relevante para os negócios, um design DDD pode usar EF com alguns objetos de dados relacionados, mas esses devem estar sempre ocultos em uma interface orientada a comportamento relevante para os negócios.
fonte
Trate o EF pelo que é, ou seja, a biblioteca de acesso a dados, que é apenas um pouco mais fortemente tipada que o ADO.NET bruto. Eu não recomendaria modelar seu domínio usando classes de entidade EF, assim como não recomendaria modelar domínio usando DataSet ou DataTable brutos.
Entendo que o EF está sendo vendido como um atalho entre o acesso ao banco de dados e a modelagem de domínio. No entanto, essa abordagem é intrinsecamente falha, pois trata de dois problemas amplamente não relacionados. Houve outras tentativas no .NET de fazer uma classe executar algumas coisas completamente não relacionadas (por exemplo, .NET Remoting) e elas não terminaram bem.
Faça o DDD usando classes POCO e não permita que o esquema do banco de dados conduza seu design. Mantenha a EF dentro da camada de repositório / persistência e não permita que as entidades da EF vazem para fora.
fonte
Não.
As abstrações do Entity Framework foram criadas com o ORM, e não o DDD, em mente. A
DbSet
abstração em qualquer versão do Entity Framework nãoDbContext
chega nem perto da simplicidade de um repositório DDD - para não mencionar o que expõe um zilhão de coisas mais do que um UnitOfWork.Aqui está uma lista não exaustiva de elementos no resumo do EF Core 2.1
DbSet<TEntity>
que não precisamos no DDD:Attach(TEntity)
e todos os seus irmãosFind(Object[])
Update(TEntity)
e todos os seus irmãosIQueryable
Além de arrastar dependências desnecessárias com elas, elas obscurecem a intenção de um Repositório que normalmente expõe um comportamento de coleção muito simples. Além disso, as abstrações com vazamentos são uma tentação constante para os desenvolvedores se juntarem demais à EF e uma ameaça à Separação de Preocupações.
Conclusão: você deve agrupar essas gorduras em conceitos agradáveis e simplificados e adivinhe, o que significa introduzir classes extras.
Um exemplo relativamente sólido do que você pode fazer com EF e DDD (embora alguns pontos de vista expressos sejam discutíveis): https://kalele.io/blog-posts/modeling-aggregates-with-ddd-and-entity-framework/
Realmente não vejo a conexão entre as duas partes desta frase. Não importa a abordagem, existe no DDD uma coisa chamada Serviço de Aplicativo e é aí que você manipula a Unidade de Trabalho / Repositório (ou
DbContext
). Não em raízes agregadas.Embora possa ser uma abordagem válida se for uma troca educada, a recente tendência anti-Repositório, "Minimalismo de Entidade da Estrutura", é ilusória. Ele culpa os padrões DDD pelo atrito que ocorre com o Entity Framework, quando na verdade são os criadores da EF que não fizeram nada para tornar sua estrutura compatível com as melhores práticas prontas para uso. O tempo todo eles estão se acoplando firmemente a essa estrutura com todos os problemas em termos de segurança e manutenção de código que podem ocorrer.
fonte
Eu usei uma abordagem em que cada agregado obtém seu próprio DBContext, mapeando exatamente o que é necessário para o agregado. Eu acho que isso também foi descrito por Julie Lerman.
Isso funcionou muito bem, mas pode não ser suficiente para modelos mais interessantes, nos quais você não deseja vincular seus conceitos às suas entidades.
fonte
Apenas gostaria de compartilhar uma possível solução para consideração:
evite referenciar o projeto EF diretamente na camada de serviço
crie uma Camada de Repositório extra (usa o projeto EF e retorna Raiz Agregada)
referencie o projeto Repository Layer in Service Layer
Arquitetura :
UI
Camada Controladora
Camada de serviço
Camada de Repositório
Estrutura de entidade
Projeto Principal (contém modelos EF)
As armadilhas que vejo com essa abordagem:
se um Repositório retornar Raiz Agregada, não como a árvore do modelo EF (por exemplo, retornamos um objeto mapeado) - estamos perdendo a capacidade da EF de rastrear alterações
se a Raiz Agregada for um modelo EF - todas as suas propriedades de navegação ainda estão disponíveis , mesmo que não possamos lidar com
DbContext
isso (não fazemos referência ao projeto EF na Camada de Serviço)fonte