2010-01-12 4 views
2

동료 개발자와 객체의 등록 정보 지연로드를 통해 (가볍게두기 위해) 대화를 나누고 있습니다.제어 반전, SRP가있는 종속성 삽입 및 지연로드

  • 그는 정적 IoC 조회 호출을 사용하여 개체의 개체를 해상도 및 지연로드하는 방법을 사용합니다.
  • SRP를 위반하고 소유 서비스를 사용하여 해당 개체를 해결한다고 말합니다.

그렇다면 IoC 및 SRP에 따라 지연로드를 어떻게 처리 할 수 ​​있습니까?

게으른로드 속성을 단위 테스트 할 수 없습니다. 그는 "UserStatsService에 대한 단위 테스트가 이미 있습니다. 코드 범위가 있습니다."라고 반증합니다. 유효한 포인트이지만, "완전한"커버리지를 위해 프로퍼티는 테스트되지 않은 채로 남아 있습니다.

설정/코드 패턴

  • 프로젝트 (등, 모든 서비스, 저장소의 ctors 주입) 엄격한 의존성 삽입 (Dependency Injection) 규칙을 사용하고 있습니다.
  • 프로젝트는 캐슬을 경유하여 IoC를 사용하고 있습니다 (단 하나의 유니티와 같을 수도 있음).

예가 아래에 있습니다.

public class User 
{ 
    public Guid UserId { get; set; } 

    private UserStats _userStats; 
    // lazy-loading of an object on an object 
    public UserStats UserStats 
    { 
    get 
    { 
     if (_userStats == null) 
     { 
     // ComponentsLookup is just a wrapper around IoC 
     // Castle/Unity/etc. 
     _userStats = 
      ComponentsLookup 
      .Fetch<UserStatsService>() 
       .GetByUserId(this.UserId); 
     } 
     return _userStats; 
    } 
    } 
} 

위의 예는 객체를 지연로드하는 예를 보여줍니다. 나는 이것을 사용하지 말고 그 객체가 필요한 곳에 UI 레이어에서 UserStatsService에 액세스하려고한다.

EDIT : NHibernate가 게으른 로딩 자체의 과부하를 생성 할 수 있도록 속성을 가상화하는 게으른 로딩에 대한 NHibernate 트릭을 상기 한 한 대답은 나에게 상기시켰다. Slick, 네,하지만 우리는 NHibernate를 사용하지 않습니다.

아무도 정말로 Lazy-Loading 문제를 다루지 않습니다. 좋은 기사와 SO 질문 가까이 :

내가 게으른 로딩의 혜택을 볼 않습니다. 내 잘못을 저 지르지 마라. 나는 내가 닌자의 D.I.- 방식으로 전환 할 때까지 복잡한 유형과 그 하위 유형을 게으른 로딩이었다. 사용자층의 통계가 말하자면 100 줄의 목록에 표시되는 UI 레이어에 이점이 있습니다. 그러나 DI 덕분에 사용자 통계 (SRP를 위반하지 않고 law-of-Demeter를 위반하지 않음)를 얻으려면 몇 줄의 코드를 참조해야하며 조회의 길을 100 배 이상 확장해야합니다.

예 예, 캐싱을 추가하고 UserStatsService가 싱글 톤 패턴으로 사용되도록 코딩되도록하여 성능 비용을 크게 낮 춥니 다.

그러나 IoC와 D.I.에 구부리지 않는 [완고한] 개발자가있는 다른 사람이 있는지 궁금합니다. 규칙을 완벽하게 처리하고, 해결 방법을 정당화하기 위해 유효한 성능/코딩 포인트를 가지고 있습니다.

답변

4

엔티티 자체는 지연로드의 책임을 가져서는 안됩니다. 이것은 다른 곳에서 해결책이 될 인프라 문제입니다.

엔티티가 두 개의 별도 컨텍스트에서 사용된다고 가정 해 봅시다. 처음에는 자녀가 심하게 쓰이고 열심히로드됩니다. 두 번째에서는 드물게 사용되며 게으른로드입니다. 그것은 또한 기업의 관심사입니까? 구성은 어떻게 생겼습니까?

NHibernate는 엔티티 유형을 프록시 처리하여 이러한 질문에 응답합니다. 유형이 IList<Entity> 인 속성은 인프라에 의해 지연로드를 알고있는 구현으로 설정됩니다. 회사는 행복하게 모르고있다. 귀하의 질문과 같은 상위 참조도 처리되므로 간단한 속성 만 있으면됩니다.

우려 사항은 엔티티 외부이므로 인프라 (ORM)는 컨텍스트 및 구성 (예 : 열망/지연로드) 결정에 대한 책임이 있습니다.

+0

+1 나는 우려가 법인 외부에 있어야한다는 데 완전히 동의합니다. NHibernate (내가 어떻게 lazy-loading 프로퍼티에 과부하를 일으키는 지 알 수있다.)는 쉬울 것이다. 하지만, 우리는 NHibernate를 사용하지 않습니다. 또한 드문 경우로 (NHibernate없이) 설명하면, 많은 메모리를 사용하는 경향이 있습니다. 하위 속성은 repo 수준에서로드됩니다. 따라서 필요할 때만 사용할 수있는 고성능 Lazy-loading 개념. 나는 다른 패턴을 계속 살펴볼 것입니다. – eduncan911

+0

'IList <>'밑에 지연로드를 구현하는 것은 Hibernate와 독립적이다; 그것은 단지 쉬운 예입니다. 정적 호출에 대한 주요 이점은 상황 인식입니다. 클래스에 정적 호출을 넣으면 모든 AppDomain의 컨텍스트가 자동으로 만들어 지므로 모든 인스턴스가 정확히 같은 방식으로 작동해야합니다. 엔티티에 대한 목록 페이지 및 내보내기가 있다고 가정 해 보겠습니다. 목록 페이지는 느슨하게로드 할 수 있지만 모든 것을 처리 할 것이므로 내보내기에 대한 부담은 적을 수 있습니다. 이러한 상황 별 동작 (배치 크기와 같은 다른 것들)은 기본적으로 정적 호출에 의해 배제됩니다. –