엔터티 프레임 워크를 사용한 도메인 기반 디자인의 함정


12

내가 공부 한 DDD에 대한 많은 튜토리얼이 대부분 이론을 다루고 있습니다. 그것들은 모두 기본적인 코드 예제를 가지고 있습니다 (Pluralsight 및 이와 유사한).

웹에서는 소수의 사람들이 EDD를 사용하여 DDD를 다루는 학습서를 작성하려고 시도합니다. 잠깐 공부를 시작하면 서로 다른 점을 빨리 알 수 있습니다. 어떤 사람들은 앱을 최소한으로 유지하고 EF 위에 저장소 같은 추가 레이어를 피하는 것을 권장하고 , 다른 사람들은 추가 레이어를 생성하여 결정적으로 추가 DbContext루트를 생성하고 종종 집계 루트 에 주입 하여 SRP를 위반하는 경우가 있습니다.

의견 기반 질문을한다면 정말 죄송하지만 ...

실습에서 Entity Framework는 가장 강력하고 널리 사용되는 ORM 중 하나입니다. 불행히도 DDD를 다루는 포괄적 인 코스는 찾을 수 없습니다.


중요한 측면 :

  • Entity Framework는 UoW & Repository ( DbSet)를 기본적으로 제공 합니다

  • EF를 사용하면 모델에 탐색 속성이 있습니다

  • EF와 함께 모든 모델은 항상 사용 가능한 오프 DbContext(그들이로 표시됩니다 DbSet)

함정 :

  • 하위 모델이 집계 루트를 통해서만 영향을받는 것을 보장 할 수는 없습니다. 모델에는 탐색 속성이 있으며 모델을 수정하고 호출 할 수 있습니다.dbContext.SaveChanges()

  • DbContext당신 과 함께 모든 모델에 액세스 할 수 있습니다, 따라서 집계 루트 를 우회

  • 당신은을 통해 루트 객체의 자식에 대한 액세스를 제한 할 수 ModelBuilder있는 OnModelCreating방법 필드로 표시하여 (나는 아직도 DDD에 대해 갈 수있는 올바른 방법이다 생각하지 않는다 플러스 이것이 미래에 발생할 수 모험의 종류 어떤 평가하기 어렵습니다 - 매우 회의적 )

갈등 :

  • 집계를 반환 하는 다른 저장소 계층을 구현 하지 않으면 위에서 언급 한 함정을 부분적으로 해결할 수조차 없습니다.

  • 저장소의 추가 계층을 구현 함으로써 EF의 내장 기능을 무시하고 ( DbSet이미 모두 레포지토리 ) 앱을 지나치게 복잡하게 만듭니다.


내 결론 :

나의 무지를 용서해주십시오. 그러나 위의 정보에 근거하면 – 그것은 Entity Framework 도메인 주도 설계에 적합하지 않거나 도메인 주도 설계가 불완전 하고 오래된 접근법입니다.

각 접근법마다 장점이 있다고 생각하지만 지금은 완전히 잃어 버렸고 DDD와 EF를 조정하는 방법에 대한 최소한의 아이디어가 없습니다.


내가 틀렸다면 누구나 EF를 사용하여 DDD를 수행하는 방법에 대한 간단한 지시 사항을 자세히 설명하거나 적절한 코드 예제를 제공 할 수 있습니까?


EF 작동 방식에 대한 이해에 따라 여기 에 단계를 자세히 설명했습니다 . 여전히 이러한 단계는 탐색으로 어린이에 액세스하는 문제를 처리하지 않습니다. 속성 또는 DbContext에 의해 DbSets 해제
Alex Herman

답변:


8

DDD와 EF는 서로 관련이 없습니다.

DDD는 모델링 개념입니다. 이는 도메인, 비즈니스 요구 사항에 대해 생각하고 모델링하는 것을 의미합니다. 특히 객체 지향의 맥락에서 비즈니스 기능과 기능을 반영하는 디자인을 만드는 것을 의미합니다.

EF는 지속성 기술입니다. 주로 데이터 및 데이터베이스 레코드와 관련이 있습니다.

이 두 사람은 크게 이혼했습니다. DDD 디자인은 후드 아래에서 EF를 어떤 형태로든 사용할 수 있지만 두 가지 방식으로 다른 방식으로 상호 작용해서는 안됩니다.

도메인 기반 디자인에 대한 일부 해석은 실제로 데이터 모델링을 옹호하므로 이것이 귀하의 질문에 대한 것이라고 생각합니다. 이 해석에서 "엔티티"및 "값 개체"는 본질적으로 함수가없는 데이터 홀더 일 뿐이며, 디자인은 이러한 속성이 보유하는 속성과 서로 간의 관계에 관한 것입니다. 이러한 맥락에서 DDD 대 EF가 나타날 수 있습니다.

그러나이 해석은 결함이 있으므로 완전히 무시하는 것이 좋습니다.

결론 : DDD와 EF는 상호 배타적이지 않으며 데이터 모델링이 아닌 적절한 객체 모델링을 수행하는 한 실제로는 서로 관련이 없습니다. DDD 객체는 어떤 모양이나 형태로도 EF 아티팩트가 아니어야합니다. DDD 엔티티는 예를 들어 EF "엔티티" 가 아니 어야합니다 . 일부 비즈니스 관련 기능 내에서 DDD 디자인은 일부 관련 데이터 오브젝트와 함께 EF를 사용할 수 있지만 비즈니스 관련 동작 지향 인터페이스에서 항상 숨겨져 야합니다.


1
EF는 시간 절약에 불과합니다. 집계의 변경 추적 및 지속성은 EF가 이미 많은 도움을주는 곳입니다. 불행히도 현재 구성 수준에서 집계 모양을 정의 할 수있는 방법이 없습니다.
Pavel Voronin

6

EF는 원시 ADO.NET보다 약간 더 강력하게 지정된 데이터 액세스 라이브러리입니다. 원시 DataSet 또는 DataTable을 사용하여 도메인을 모델링하지 않는 것처럼 EF 엔터티 클래스를 사용하여 도메인을 모델링하지 않는 것이 좋습니다.

EF가 데이터베이스 액세스와 도메인 모델링 사이의 지름길로 판매되고 있음을 이해하지만이 방법은 크게 관련이없는 두 가지 문제를 해결하므로 본질적으로 결함이 있습니다. .NET에서 클래스가 완전히 관련되지 않은 것들 (예 : .NET Remoting)을 수행하게하려는 다른 시도가 있었지만 끝내지 못했습니다.

POCO 클래스를 사용하여 DDD를 수행하고 데이터베이스 스키마가 설계를 주도하게하지 마십시오. EF를 저장소 / 지속성 계층 내부에 유지하고 EF 엔티티가 외부로 누출되지 않도록하십시오.


5

Entity Framework에서 UbW 및 리포지토리 (DbSet)를 즉시 사용 가능

아니.

Entity Framework 추상화는 DDD가 아닌 ORM을 염두에두고 작성되었습니다. DbSet엔티티 프레임 워크의 모든 버전에서 추상화는 DDD 저장소의 단순 근처에 아무데도 -하지 언급에 DbContext의 UnitOfWork보다 엄청나게 많은 것들을 제공합니다.

다음은 EF Core 2.1의 요약 DbSet<TEntity>에서 DDD에 필요하지 않은 요소의 전체 목록입니다 .

  • Attach(TEntity) 그리고 모든 형제
  • Find(Object[])
  • Update(TEntity) 그리고 모든 형제
  • 구현 IQueryable

불필요 한 종속성을 끌어다 놓는 것 외에도 저장소의 의도를 모호하게하여 일반적으로 매우 간단한 수집 동작을 제공합니다. 또한 유출되는 추상화는 개발자가 EF에 너무 많이 결합하고 우려 분리에 대한 위협을 끊임없이 유혹합니다.

결론 :이 지방을 멋지고 간소화 된 개념으로 싸서 무엇을 추측해야합니까? 즉, 추가 수업을 도입해야한다는 것을 의미합니다.

EF 및 DDD로 할 수있는 일에 대한 비교적 건전한 예 (표현 된 관점은 논란의 여지가 있지만) : https://kalele.io/blog-posts/modeling-aggregates-with-ddd-and-entity-framework/

다른 사람들은 결정적으로 여분의 레이어를 생성하고 종종 DbContext를 집계 루트에 주입하여 SRP를 위반합니다.

나는이 문장의 두 부분 사이의 연관성을 실제로 보지 못한다. 접근 방식에 관계없이 DDD에는 응용 프로그램 서비스라는 것이 있으며 여기서 작업 단위 / 저장소 (또는 DbContext) 를 조작 할 수 있습니다. 뿌리에 있지 않습니다.

교육적인 트레이드 오프 인 경우에는 올바른 접근 방법이 될 수 있지만 최근의 반 저장소, "Entity Framework 미니멀리즘"추세는 망상입니다. 실제로 프레임 워크가 모범 사례와 호환되도록 프레임 워크를 만들지 않은 EF 제작자 인 경우 Entity Framework에서 발생하는 마찰에 대해 DDD 패턴을 비난합니다. 코드 보안 및 유지 관리 측면에서 문제가 발생하는 프레임 워크와 밀접하게 연결되어 있습니다.


2

갈등 :

집계를 반환하는 다른 저장소 계층을 구현하지 않으면 위에서 언급 한 함정을 부분적으로 해결할 수조차 없습니다.

저장소의 추가 계층을 구현하여 EF의 내장 기능을 무시하고 (DbSet은 이미 저장 소임) 앱을 너무 복잡하게 만듭니다.

모든 Aggregate가 자체 DBContext를 가져와 Aggregate에 필요한 것을 매핑하는 접근 방식을 사용했습니다. Julie Lerman도 이것에 대해 설명했다고 생각합니다.

이것은 잘 작동했지만 개념을 엔터티에 연결하지 않으려는 더 흥미로운 모델에는 충분하지 않을 수 있습니다.



DBContext Per Aggregate 접근법의 이점이 있습니까? 이것이 EF로 DDD를 구현하는 기본 방법입니까?
Alex Herman

Julie Lerman이 바운드 컨텍스트 당 DbContext를 의미하지 않습니까?
Mvision

0

고려할 가능한 해결책을 공유하고 싶습니다.

  1. 서비스 계층에서 EF 프로젝트를 직접 참조하지 마십시오

  2. 추가 리포지토리 레이어 생성 (EF 프로젝트 사용 및 집계 루트 반환)

  3. 서비스 계층 프로젝트의 리포지토리 계층 참조

건축 :

  • UI

  • 컨트롤러 레이어

  • 서비스 계층

  • 리포지토리 레이어

  • 엔터티 프레임 워크

  • 핵심 프로젝트 (EF 모델 포함)


이 접근법으로 볼 수있는 함정 :

  • 리포지토리가 EF 모델 트리가 아닌 집계 루트를 반환하는 경우 (예 : 매핑 된 개체를 반환) EF의 변경 내용 추적 기능이 손실됩니다

  • Aggregate Root가 EF 모델 인 경우 처리 할 수 ​​없지만 모든 탐색 속성 을 계속 사용할 수 있습니다 DbContext(서비스 계층에서 EF 프로젝트를 참조하지 않음)

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.