2009-03-28 3 views
18

도메인 계층 (모듈, 모델, 엔티티, 도메인 서비스 등)의 모든 인터페이스를 인프라 계층 내에서 그룹화하는 것이 합리적입니까? 그렇지 않은 경우이 모든 것을 공유 라이브러리에 그룹화하는 "공유 된"프로젝트/구성 요소를 만드는 것이 합리적입니까? 결국, "인프라 계층"의 정의에는 "도메인, 응용 프로그램 및 UI 계층에 대한 공유 라이브러리"가 포함됩니다.DDD : 도메인 인터페이스를 유지할 인프라는 어디입니까?

저는 DDD 레이어 주위에 코드베이스를 설계하려고합니다 : UI, 응용 프로그램, 도메인, 인프라. 이것은 4 개의 프로젝트를 존중하게 만듭니다. 요점은 인프라 계층을 도메인 계층에서 참조한다는 것입니다. 그러나 도메인 계층 프로젝트에서 인터페이스를 정의하고 IPost에 대해 말하면 IPostRepository.Save (IPost post) 메서드를 정의 할 때 Infrastructure 프로젝트에서 Domain Layer 프로젝트를 참조해야 할 때 circulur 참조를 갖습니다. . 따라서 "공유 라이브러리의 모든 인터페이스 정의"에 대한 아이디어입니다.

리포지토리는 개체를 저장해야한다고 생각해서는 안됩니다 (IPostRepository.Save (IPost 게시)) 대신 개체의 매개 변수를 기대합니다. 그러나 Save()에서는 긴 매개 변수 집합이 될 수 있습니다. 이 객체가 지나치게 복잡지고 때 표시 이상적인 상황이 될 수 있으며, 추가 가치 개체는 그것을 들여다해야합니다.

생각을?

답변

24

에릭, 나는 한 쌍을 떠나기 때문에 너무 늦게 응답 해 주신 것을 용서합니다. 저장소 배치 위치와 관련하여 필자는 개인적으로 항상 저장소를 전용 인프라 계층 (예 : MyApp.Data.Oracle)에 배치하지만 리포지토리가 도메인 계층에서 준수해야하는 인터페이스를 선언합니다.
내 프로젝트에서 응용 프로그램 계층은 도메인 및 인프라 계층을 구성해야하기 때문에 도메인 및 인프라 계층에 액세스해야합니다.
응용 프로그램 계층은 적절한 인프라를 도메인에 주입하는 역할을합니다. 도메인은 그것이 말하는 인프라가 무엇인지 알지 못하고, 어떻게 호출해야 하는지를 알고 있습니다. 물론 Structure Map과 같은 IOC 컨테이너를 사용하여 종속성을 도메인에 주입합니다. 다시 말하면 DDD가 프로젝트를 구조화하는 방법이라고 말하는 것은 아닙니다. 단지 방법 일뿐입니다. 아키텍처는 내 앱입니다. 건배.

+2

뛰어난 Geobarteam. "도메인"의 인터페이스 정의, 리포지토리는 별도의 어셈블리 (MySqlProviver, MsSqlProvider, XmlProvider 등) 및 일부 유형의 IOC 컨테이너 (Castle Windsor가 좋아)를 App 계층에서 연결하는 데 사용합니다. – eduncan911

+1

ASP.NET MVC의 경우 실제로 컨트롤러를 UI에 쉽게 주입 할 수 있습니다 (UI 레이어)에서 성 Windosr. 스티븐 Sanderson은 ASP.NET MVC 프레임 워크 미리보기에서 좋은 예를했다. 도메인 신속한 책 나는 UI, App 및 Domain 모두 Infra를 사용할 수 있다고 말합니다. – eduncan911

+1

내가 가진 유일한 문제점은 내 책에 인프라가 아무 것도 언급하지 않는다는 것입니다. UI-> App, Domain 및 Infra. App-> Domain 및 Infra. 그리고, Domain-> Infra. 나는 알고있다, 그것은 모두 가이드 라인이된다고 여겨진다. – eduncan911

3

그래서 주저하지 말고 내가 DDD의 새로운 조용 해요 당신이 동의하지 않는다면 논평 해달라고 부탁드립니다.

개인적으로 나는 왜 당신이 참조해야하는지 이해하지 못합니다. 도메인의 인프라 계층을 유지하십시오. 제 생각에는 도메인은 인프라에 의존해서는 안됩니다. Domain 개체는 실행중인 데이터베이스 나 메일을 보내는 데 사용되는 메일 서버 유형에 대해 완전히 모르는 상태 여야합니다. 인프라에서 도메인을 추상화하면 재사용하기가 더 쉽습니다. 왜냐하면 도메인은 실행중인 인프라에 대해 알지 못하기 때문입니다.

내 코드에서 수행하는 작업은 인프라 계층의 도메인 계층을 참조합니다 (반대는 아니지만). 리포지토리는 도메인의 상태를 보존하는 역할을하기 때문에 도메인 개체를 알고 있습니다. 내 리포지토리에는 내 루트 집계 (get (id), getall(), save (object), delete (object) 및 내 컨트롤러 내에서 호출되는 기본 CRUD 작업이 포함되어 있음)

마지막 프로젝트에서 수행 한 작업 내 접근 방식은 순전히 DDD가 아니지만 꽤 잘 작동했다.) 나는 리포지토리를 인터페이스로 추상화했다. 구체적인 유형의 리포지토리를 전달하여 루트 집계를 인스턴스화해야했다.

루트 집계를 통해 인스턴스화해야했다. 저장소의 Get (ID) 또는 Create() 메소드를 사용하여 저장소 특정 개체를 구성하는 구체적인 저장소가 자신을 전달하여 집계가 자신의 상태와 자식 개체의 상태를 유지할 수 있지만 구체적인 구현을 알지 못합니다. 저장소의. 예 :

public class PostRepository:IPostRepository 
{ 
    ... 
    public Post Create() 
    { 
     Post post=new Post(this); 
     dbContext.PostTable.Insert(post); 
     return post; 
    } 
    public Save(post) 
    { 
     Post exitingPost=GetPost(post.ID); 
     existingPost = post; 
     dbContext.SubmitChanges(); 
    } 
} 

public class Post 
{ 

    private IPostRepository _repository 
    internal Post(IPostRepository repository) 
    { 
     _repository = repository; 
    } 
    ... 
    Public Save() 
    { 
     _repository.Save(this); 
    } 

} 
+0

나는 이것이 어디로 가고 있는지 안다. DDD 서적에서 저장소가 Infrastructure 계층에 있다고 언급 한 것입니다. 하지만 인터넷에서 찾은 정보가 충돌하면 도메인 계층에 리포지토리가 저장됩니다. – eduncan911

+0

또한 UI 계층은 "응용 프로그램, 도메인 및 인프라"에 액세스하고 응용 프로그램 계층은 "도메인 및 인프라"에 액세스하고 마지막으로 도메인 계층은 "인프라"에 액세스 할 것을 권고합니다. 이것은 "DOmain Driven Design"이라는 책에서 발췌 한 것입니다. 따라서이 이유는 무엇입니까? – eduncan911

+11

이것은 어려운 정보입니다. 내가 생각하기에 * 내가 알아 낸 것은 리포지토리의 * 인터페이스 *가 도메인의 "솔기"를 정의하기 때문에 도메인 계층에 들어가는 것입니다. 리포지토리의 * 구현은 인프라 계층에 있으며, 현재 응용 프로그램 컨텍스트에서 도메인을 완전히 추출하고 완전히 새로 작성하기로 결정한 경우 리포지토리의 인터페이스가 필요하지만 구현이 반드시 필요하지는 않습니다. – jlembke

3

나는 당신에게 Onion architecture을 권하고 싶습니다. DDD와 매우 잘 어울립니다. 아이디어는 저장소 인터페이스 그냥 직접 도메인 및 참조 엔티티 외부 층에 앉아 있다는 것입니다 :

IPostRepository.Save(Post post)

도메인 모두에서 저장소에 대해 알 필요가 없다.

인프라 계층은 도메인이나 다른 사람이 참조하지 않으며 다른 I/O 관련 항목들 사이의 저장소에 대한 구체적인 구현을 포함합니다.이 경우 다양한 도우미가있는 공용 라이브러리를 Application Core라고하며 누구든지이를 참조 할 수 있습니다.

+0

잘못되었습니다. . 도메인 저장소 리포지토리 및 게이트웨이 인터페이스 인프라 "레이어"가 구현합니다. – Mik378

관련 문제