Una gran cantidad de tutoriales sobre DDD que estudié cubren principalmente la teoría. Todos tienen ejemplos de código rudimentario (Pluralsight y similares).
En la web también hay intentos de algunas personas de crear tutoriales que cubran DDD con EF. Si comienza a estudiarlos brevemente, notará rápidamente que difieren mucho entre sí. Algunas personas recomiendan mantener la aplicación mínima y evitar la introducción de capas adicionales, por ejemplo, el repositorio encima de EF , otras están decididamente generando capas adicionales, a menudo incluso violando SRP al inyectar DbContext
en Raíces Agregadas.
Me disculpo terriblemente si hago una pregunta basada en una opinión, pero ...
Cuando se trata de practicar, Entity Framework es uno de los ORM más potentes y ampliamente utilizados. Lamentablemente, no encontrará un curso completo que abarque DDD.
Aspectos importantes:
Entity Framework trae UoW & Repository (
DbSet
) fuera de la cajacon EF sus modelos tienen propiedades de navegación
con EF todos los modelos son siempre disponible fuera
DbContext
(que se representan como unaDbSet
)
Trampas:
no puede garantizar que sus modelos secundarios solo se vean afectados por la raíz agregada: sus modelos tienen propiedades de navegación y es posible modificarlos y llamar
dbContext.SaveChanges()
con la
DbContext
que se puede acceder a cada modelo, por tanto, eludir agregado Raízpuede restringir el acceso a los elementos secundarios del objeto de la raíz a través
ModelBuilder
deOnModelCreating
método marcándolos como campos - Todavía no creer que es la forma correcta de hacer las DDD y además es difícil de evaluar qué tipo de aventuras que esto puede conducir en el futuro ( bastante escépticos )
Conflictos:
sin implementar otra capa de repositorio que devuelva Agregado, ni siquiera podemos resolver en parte las trampas mencionadas anteriormente
Al implementar una capa adicional de repositorio, estamos ignorando las características integradas de EF (todo
DbSet
ya es un repositorio) y complicando demasiado la aplicación
Mi conclusión:
Perdone mi ignorancia, pero en base a la información anterior, o bien Entity Framework no es adecuado para el diseño dirigido por dominio o el diseño dirigido por dominio es un enfoque imperfecto y obsoleto .
Sospecho que cada uno de los enfoques tiene sus méritos, pero ahora estoy completamente perdido y no tengo la menor idea de cómo conciliar EF con DDD.
Si me equivoco, ¿podría alguien al menos detallar un conjunto simple de instrucciones (o incluso proporcionar ejemplos de código decente) de cómo hacer DDD con EF, por favor?
Respuestas:
DDD y EF tienen poco o nada que ver entre sí.
DDD es un concepto de modelado. Significa pensar en el Dominio, los Requisitos del Negocio y modelarlos. Especialmente en el contexto de la orientación a objetos, significa crear un diseño que refleje las funciones y capacidades comerciales.
EF es una tecnología de persistencia. Se ocupa principalmente de datos y registros de bases de datos.
Estos dos están muy divorciados. Un diseño DDD puede usar EF de alguna forma debajo del capó, pero los dos no deben interactuar de ninguna otra manera.
Algunas interpretaciones del diseño impulsado por dominios en realidad abogan por el modelado de datos, y creo que de esto se trata su pregunta. En esta interpretación, las "Entidades" y los "Objetos de valor" son esencialmente poseedores de datos sin funciones únicamente, y el diseño se refiere a qué propiedades tienen y qué relación tienen entre sí. En este contexto, puede aparecer DDD vs. EF.
Sin embargo, esta interpretación es defectuosa, y recomendaría ignorarla por completo.
En conclusión : DDD y EF no son mutuamente excluyentes, en realidad son irrelevantes entre sí, siempre que esté realizando un modelado de objetos adecuado y no un modelado de datos. Los objetos DDD no deben tener ninguna forma o artefactos EF. Las entidades DDD no deben ser EF "entidades", por ejemplo. Dentro de alguna función relevante para el negocio, un diseño DDD puede usar EF con algunos objetos de datos relacionados, pero estos siempre deben estar ocultos bajo una interfaz orientada al comportamiento relevante para el negocio.
fuente
Trate a EF por lo que es, es decir, la biblioteca de acceso a datos que tiene un tipo ligeramente más fuerte que ADO.NET sin formato. No recomendaría modelar su dominio usando clases de entidad EF al igual que no recomendaría modelar el dominio usando DataSet o DataTable sin formato.
Entiendo que EF se está vendiendo como un acceso directo entre el acceso a la base de datos y el modelado de dominios, sin embargo, este enfoque es intrínsecamente defectuoso ya que aborda dos problemas en gran medida no relacionados. Hubo otros intentos en .NET para hacer que una clase realizara algunas cosas completamente no relacionadas (por ejemplo, Remoto de .NET) y no terminaron bien.
Haga el DDD usando clases POCO y no permita que el esquema de la base de datos controle su diseño. Mantenga EF dentro del repositorio / capa de persistencia y no permita que las entidades EF se filtren afuera.
fuente
No.
Las abstracciones de Entity Framework se crearon teniendo en cuenta ORM, no DDD. La
DbSet
abstracción en cualquier versión de Entity Framework no se acerca a la simplicidad de un Repositorio DDD, sin mencionarDbContext
que expone un millón de cosas más que UnitOfWork.Aquí hay una lista no exhaustiva de elementos en el resumen de EF Core 2.1
DbSet<TEntity>
que no necesitamos en DDD:Attach(TEntity)
y todos sus hermanosFind(Object[])
Update(TEntity)
y todos sus hermanosIQueryable
Además de arrastrar dependencias innecesarias con ellos, estos oscurecen la intención de un Repositorio que normalmente expone un comportamiento de recopilación muy simple. Además, las abstracciones permeables son una tentación constante para que los desarrolladores se acoplen demasiado a EF y una amenaza para la Separación de preocupaciones.
En pocas palabras: debe envolver estos gorditos en conceptos agradables y simplificados y adivinar qué, eso significa introducir clases adicionales.
Un ejemplo relativamente sólido de lo que puede hacer con EF y DDD (aunque algunos puntos de vista expresados son discutibles): https://kalele.io/blog-posts/modeling-aggregates-with-ddd-and-entity-framework/
Realmente no veo la conexión entre las dos partes de esta oración. No importa el enfoque, hay una cosa en DDD llamada Application Service y ahí es donde manipulas la Unidad de Trabajo / Repositorio (o
DbContext
). No en raíces agregadas.Si bien podría ser un enfoque válido si fuera una compensación educada, la reciente tendencia anti-repositorio, "minimalismo del marco de la entidad" es delirante. Culpa a los patrones DDD por la fricción que ocurre con Entity Framework cuando realmente son los creadores de EF los que no hicieron nada para que su marco cumpla con las mejores prácticas de fábrica. Mientras tanto, se están uniendo estrechamente a ese mismo marco con todos los problemas en términos de seguridad de código y mantenibilidad que pueden surgir.
fuente
He utilizado un enfoque en el que cada Agregado obtiene su propio DBContext, mapeando justo lo que se necesita para el Agregado. Creo que esto también ha sido descrito por Julie Lerman.
Esto funcionó muy bien, pero podría no ser suficiente para modelos más interesantes, donde no desea vincular sus conceptos a sus entidades.
fuente
Solo me gustaría compartir una posible solución para su consideración:
evite hacer referencia al proyecto EF en la capa de servicio directamente
crear una capa de repositorio adicional (usa el proyecto EF y devuelve la raíz agregada)
referenciar la capa de repositorio en el proyecto de capa de servicio
Arquitectura :
UI
Capa de controlador
Capa de servicio
Capa de repositorio
Marco de la entidad
Proyecto principal (contiene modelos EF)
Las trampas que veo con este enfoque:
Si un repositorio devuelve raíz agregada no como árbol modelo EF (por ejemplo, devolvemos un objeto mapeado), estamos perdiendo la capacidad de EF de rastrear cambios
si Aggregate Root es un modelo EF, todas sus propiedades de navegación aún están disponibles , aunque no podamos tratarlas
DbContext
(no hacemos referencia al proyecto EF en la capa de servicio)fuente