[.net] DTO를 도메인 개체에 매핑하는 모범 사례

DTO 를 도메인 개체 에 매핑하는 것과 관련된 많은 질문을 보았지만 그들이 내 질문에 답하지 못했다고 생각했습니다. 이전에 많은 방법을 사용해 왔고 내 의견이 있지만 좀 더 구체적인 것을 찾고 있습니다.

그 상황:

우리는 많은 도메인 객체를 가지고 있습니다. CSLA 모델을 사용하므로 도메인 개체가 매우 복잡 할 수 있고 자체 데이터 액세스가 포함됩니다. 당신은 이것들을 와이어로 전달하고 싶지 않습니다. 우리는 여러 형식 (.Net, JSON 등)으로 데이터를 반환하는 몇 가지 새로운 서비스를 작성할 것입니다. 이를 위해 (그리고 다른 이유들) 우리는 또한 유선상에서 전달할 린 데이터 전송 객체를 생성하고 있습니다.

내 질문은 : DTO와 도메인 개체를 어떻게 연결해야합니까?

첫 번째 반응은 Fowler, DTO 패턴 유형 솔루션 을 사용하는 입니다. 나는 이것을 여러 번 보았고 나에게 옳다고 느낀다. 도메인 개체에 DTO에 대한 참조가 없습니다. 도메인 개체에서 DTO를 만들기 위해 외부 엔터티 ( “매퍼”또는 “어셈블러”)가 호출됩니다. 일반적으로 도메인 개체 측에는 ORM 이 있습니다. 이것의 단점은 “매퍼”가 실제 상황에 대해 매우 복잡 해지는 경향이 있고 매우 취약 할 수 있다는 것입니다.

또 다른 아이디어는 도메인 개체가 단순한 데이터 개체이기 때문에 DTO를 “포함”하는 것입니다. 도메인 개체 속성은 내부적으로 DTO 속성을 참조하고 요청이있을 경우 DTO를 반환 할 수 있습니다. 나는 이것에 아무런 문제가 없다는 것을 알 수는 있지만 잘못된 것 같습니다. NHibernate 를 사용 하는 사람들 이이 방법을 사용 하는 것으로 보이는 기사를 보았습니다 .

다른 방법이 있습니까? 위의 방법 중 하나를 사용할 가치가 있습니까? 그렇다면 그 이유는 무엇입니까?



답변

도메인과 DTO 사이에있는 매퍼를 사용하는 이점은 단일 매핑 만 지원할 때는 나타나지 않지만 매핑 수가 증가함에 따라 해당 코드를 도메인에서 격리하면 도메인을 더 단순하고 간결하게 유지하는 데 도움이됩니다. 많은 추가 가중치로 도메인을 복잡하게 만들지 않을 것입니다.

개인적으로 저는 제 도메인 엔터티에서 매핑을 유지하고 “관리자 / 서비스 계층”이라고 부르는 책임을 맡기려고합니다. 이것은 애플리케이션과 리포지토리 (들) 사이에 위치하며 워크 플로우 조정과 같은 비즈니스 로직을 제공하는 계층입니다 (A를 수정하면 서비스 A가 서비스 B와 작동하도록 B도 수정해야 할 수 있음).

가능한 엔딩 형식이 많으면 방문자 패턴을 사용하여 엔터티를 변환 할 수있는 플러그 형 포맷터를 만드는 방법을 살펴볼 수 있지만 아직이 복잡한 항목에 대한 필요성을 찾지 못했습니다.


답변

Jimmy Bogard작성한 것과 같은 자동 매퍼를 사용할 수 있습니다.이 자동 매퍼 는 객체간에 연결이없고 준수되는 명명 규칙에 의존합니다.


답변

T4 템플릿을 사용하여 매핑 클래스를 만듭니다.

프로-런타임 매퍼보다 빠르게 컴파일 타임에 사람이 읽을 수있는 코드를 사용할 수 있습니다. 코드에 대한 100 % 제어 (부분 메서드 / 템플릿 패턴을 사용하여 임시로 기능을 확장 할 수 있음)

단점-특정 속성, 도메인 개체 컬렉션 등을 제외하고 T4 구문을 학습합니다.


답변

엔티티 내부에 매핑 논리를 유지한다는 것은 도메인 개체가 이제 알 필요가없는 “구현 세부 정보”를 인식한다는 것을 의미합니다. 일반적으로 DTO는 들어오는 요청에서 또는 외부 서비스 / 데이터베이스에서 읽기를 통해 외부 세계로 연결되는 게이트웨이입니다. 엔터티는 비즈니스 로직의 일부이므로 이러한 세부 정보를 엔터티 외부에 유지하는 것이 가장 좋습니다.

다른 곳에 매핑을 유지하는 것이 유일한 대안이 될 수 있지만 어디로 가야합니까? 나는 매핑 객체 / 서비스를 도입하려고 시도했지만, 결국 말하고 수행 한 것은 과잉 엔지니어링처럼 보였습니다. 저는 소규모 프로젝트에서 Automapper 등을 사용하여 약간의 성공을 거두었지만 Automapper와 같은 도구에는 자체 함정이 있습니다. Automapper의 매핑은 암시 적이며 나머지 코드와 완전히 분리되어 있기 때문에 매핑과 관련된 문제를 찾기가 꽤 어려웠습니다 ( “관심의 분리”가 아니라 “갓 포세이큰 매핑이 살고있는 곳”과 비슷 함). 때로는 추적하기 어려울 수 있습니다. Automapper가 그 용도가 없다고 말하는 것은 아닙니다. 저는 매핑이 문제를 피하기 위해 가능한 한 명확하고 투명해야한다고 생각합니다.

매핑 서비스 계층을 생성하는 대신 DTO 내부에 매핑을 유지하는 데 많은 성공을 거두었습니다. DTO는 항상 응용 프로그램의 경계에 있기 때문에 비즈니스 개체를 인식하고 여기에서 매핑하는 방법을 파악할 수 있습니다. 매핑 수가 합리적인 양으로 확장 되더라도 깨끗하게 작동합니다. 모든 매핑이 한곳에 있으며 데이터 계층, 부패 방지 계층 또는 프레젠테이션 계층 내에서 여러 매핑 서비스를 관리 할 필요가 없습니다. 대신 매핑은 요청 / 응답과 관련된 DTO에 위임 된 구현 세부 정보 일뿐입니다. serializer는 일반적으로 속성과 필드를 유선을 통해 전송할 때만 직렬화하므로 문제가 발생하지 않아야합니다. 개인적으로 저는 이것이 가장 깨끗한 옵션임을 발견했고 제 경험상


답변

도메인 개체를 매개 변수로 사용하는 DTO 클래스 내부에서 생성자를 구현하는 방법은 무엇입니까?

말 … 이런거

class DTO {

     // attributes 

     public DTO (DomainObject domainObject) {
          this.prop = domainObject.getProp();
     }

     // methods
}


답변

또 다른 가능한 솔루션 : http://glue.codeplex.com .

풍모:

  • 양방향 매핑
  • 자동 매핑
  • 다른 유형 간의 매핑
  • 중첩 된 매핑 및 병합
  • 목록과 배열
  • 관계 확인
  • 매핑 테스트
  • 속성, 필드 및 방법


답변

Object-to-Object 매퍼 인 Otis를 사용해 볼 수도 있습니다. 개념은 NHibernate 매핑 (속성 또는 XML)과 유사합니다.

http://code.google.com/p/otis-lib/wiki/GettingStarted