2010-02-22 4 views
3

DDD를 사용할 때 가장 좋은 방법을 찾고 있으며 가장 의미가 있거나 올바른 방법에 대해 토론하고 있습니다.리포지토리 및 서비스 디자인 질문

참고 : 모든 코드는 의사 코드입니다. 다음 Conceder

:

public interface IDomainEntityAService 
{ 
    void CreateMyObject(DomainEntityA myobject); 
    DomainEntityA RetrieveDomainEntityA(long someId); 
    //Other operations that handle the business logic dealing with MyObject 
} 

우리는 또한 전문 필요성을 용이하게하기 위해 IDomainEntityAService의 일부를 사용하는 다른 서비스가있다.

public class DomainEntityB 
{ 
    public string Name { get; set; } 
    public IList<DomainEntityA> DomainEntityAList { get; set; } 
} 

지금 우리의 질문에 온다 : OtherInformation는 다음이 포함

public interface IDomainEntityBService 
{ 
    DomainEntityB GetDomainEntityB(); 
} 

. 우리는 다음과 같이 OtherInformation을 유지하기 위해 저장소를 사용하여 조사하고 있습니다 :

public interface IDomainEntityBRepository 
{ 
    void Add(DomainEntityB information); 
    DomainEntityB Get(long someId); 
} 

우리는 우리가 이상적으로 DomainEntityB에 대한 DomainEntityAList의 목록을 검색 IDomainEntityAService의 논리를 재사용 할 것이다 가능한 한 드라이로 일을 유지하고자하기 때문에 . 어느 것이 가장 합리적인가?

A)는 IDomainEntity 브리 포세 티토 에있는 IDomainEntityAService에 대한 참조를가집니다.

public class SqlDomainEntityBRepository : IDomainEntityBRepository 
{ 

    public SqlDomainEntityBRepository(IDomainEntityAService domainEntityAService, Database database) 
    { 

    } 

    public void Add(DomainEntityB information) 
    { 
     //save DomainEntityB to SQL 
    } 
    public DomainEntityB Get(long someId) 
    { 
     //Get OtherInformation.Name from SQL 
     //use domainEntityAService.Get() to populate the list of DomainEntityAList 
     //return DomainEntityB 
    } 
} 

B) IDomainEntityBRepository 만 SQL 물건을 처리하고 우리는 우리가 OtherInformation에 대한 특정 DAL 객체를 만들

public class DomainEntityBService : IDomainEntityBService 
{ 
    public DomainEntityBService(IDomainEntityAService domainEntityAService, IDomainEntityBRepository repo) 
    { 
    } 
    public DomainEntityB GetDomainEntityB() 
    { 
     var domainEntityB = _repo.Get(someId); 
     domainEntityB.DomainEntityAList = _domainEntityAService.GetAll(someId); 
     return domainEntityB; 
    } 
} 

C) MyObjects의 목록을 채우는 IHaveOtherInformation에 대한 서비스 레이어를 사용하고 우리가를 사용 서비스 계층은 OtherInformation의 인스턴스를 구성한다.

public class DomainEntityBDAL 
{ 
    public string Name { get; set; } 
    public IList<int> DomainEntityAListIds { get; set; } 
} 

그러면 우리는 OtherInformationDAL을 검색하고 코드는 다음과 같을 것입니다 :

public class DomainEntityBService : IDomainEntityBService 
{ 

    public DomainEntityBService(IDomainEntityAService domainEntityAService, IDomainEntityBRepository repo) 
    { 
    } 
    public DomainEntityB GetDomainEntityB() 
    { 

     var domainEntityBDAL = _repo.Get(someId); 
     DomainEntityB result = new DomainEntityB() { Name = domainEntityBDAL.Name }; 
     foreach (var id in domainEntityBDAL.DomainEntityAListIds) 
     { 
      result.DomainEntityAList.Add(_domainEntityAService.Get(id)); 
     } 
     return result; 
    } 
} 

D) 와우 우리는 완전히 벗어나 있습니다!

여러분의 도움에 감사드립니다.

편집 주 :

어쩌면 영어 설명을 더 내 질문을 설명하는 데 도움이 될 수 있습니다. 우리는 집계 루트 인 DomainEntityA를 가지고 있습니다. DomainEntityA를 다루는 모든 로직을 처리하는 해당 서비스가 있습니다.

이제 우리는 집계 루트 인 DomainEntityB도 갖습니다. 그러나 DomainEntityB에는 DomainEntityAs의 목록이 있습니다. DomainEntityAs는 자체적으로 살아갈 수 있지만 DomainEntityB는 DomainEntityA의 목록 없이는 살 수 없습니다.

DomainEntityB의 DomainEntityA 항목 목록을로드하고 DomainEntityA의 모든 로직을 유지하는 방법은 무엇입니까?

DomainEntityBService에서 DomainEntityAService를 다시 사용 하시겠습니까?
DomainEntityBService에 별도의 DomainEntityARepository를 만드시겠습니까?

우리는 현재 EntLib을 사용하고 있지만 DAL 구현에 대한 자세한 내용은 디자인 정보를 참조하십시오.

+0

이 질문에 대한 답은 어떤 DAL 구현을 사용해야합니까? 왜 그렇게 Entlib에 설정되어 있습니까? –

+0

특정 DAL 구현으로이 작업이 더 쉬워 진 경우 모든 작업을 수행 할 수 있습니다. 우리는 과거에 Entlib을 사용했고 Repository 패턴과 함께 사용하려고했습니다. –

답변

0

대신 유형을 연결할 수있는 일반 인터페이스를 사용 하시겠습니까? 좋아요 :

public interface IRepository<T> 
{ 
    T Get(object id); 
    void Save(T value); 
    void Update(T value); 
    void Delete(T value); 
    IList<T> GetAll(); 
} 

사용하는 구현은 유형을 읽고 데이터베이스에 맞는 방법을 알아야합니다. 그것은 요컨대 저장소 패턴입니다. Entlib에 완전히 설정되지 않은 경우 NHibernate를 탐색하십시오. 나는 그것이 저장소 패턴을 잘 보완한다는 것을 발견했다. 내 블로그에 this topic에 대해 많이 작성 했으므로 더 알고 싶다면 거기에 갈 수 있습니다.

+0

정보를 주셔서 감사합니다,하지만 내 편집을 참조하십시오. T의 하위 노드가 (완전히 다른 도메인의) 집계 루트 인 경우 저장소에있는 항목을로드하는 방법은 무엇입니까? –

+0

NHibernate는 "T의 자식들"(일명 상속)을 처리 할 수 ​​있습니다. 나는 당신이 "다른 도메인의 집계 루트"가 무엇을 의미하는지 알지 못한다. 그러나 NHibernate는 당신이 생각해 낼 수있는 관계를 거의 다룰 수있다. –

+0

나는 상속을 의미하지 않는다. "B"는 "A"의 목록을 가지고있다. "A"는 자체적으로 살아갈 수 있고 다른 서비스/애플리케이션에 의해 소비 될 수 있습니다. 이제 "B"는 "B"의 유효한 인스턴스가 되려면 "A"의 목록이 필요합니다. 모든 "A"("B"의 인스턴스에 대해)를 얻으려면 웹 서비스 호출을해야합니다. 어디에서 전화해야합니까? "B"에 대한 "A"의로드가 DAL, 서비스 계층 또는 그 밖의 다른 곳에서 실행되도록 호출해야합니까? –

0

여기서는 데이터베이스에 저장한다는 가정을하고 있습니다.

이것에 대한 대답은 당신이 당신의 영속성 엔진으로 사용하고있는 것에 크게 의존합니다. 직접 손으로 끈기를 굴린 경우 C은 N + 1 검색어를 볼 수 있기 때문에 옵션이 아닙니다. B이 코드 첫 번째 선택 일 가능성이 가장 높습니다. 코드 재사용을 제공하기 때문입니다.

는 NHibernate에 같은 것을 사용하는 경우 내가 저장소 패턴 대신

  • (다음 단위 테스트 할 수있는) 객체로 복잡한 쿼리를 캡슐화를 사용하지 않는 것이 좋습니다 거라고 말했다 가졌어요.
  • 직접

난이 도움이되기를 바랍니다 세션을 사용!

+0

DAL에 대해 EntLib을 사용할 가능성이 큽니다. –

+0

A가 나쁜 것으로 간주되는 이유에 대한 정보가 있었습니까? 저장소가 하나 이상의 위치에서 모아진 객체를 반환하는 것은 나쁜 습관입니까? 예 : SQL, XML 및 파일에서 쿼리해야하는 도메인 모델의 인스턴스를 만들 수 있습니까? 또는 저장소가 하나의 데이터 저장소 만 다루어야합니까? –