2009-06-27 4 views
1

나는 개발중인 SDK에있는 내부 종속성을 관리하는 방법을 알아내는 데 어려움을 겪고 있습니다. 어떤 이유로 모든 작업을 수행하기가 어려울 것 같습니다. 내부 의존성 관리

내가이 수업을 말 :

class Table 
{ 
    Table(string name,IQueryProvider provider, IComObject comobject) {} 
} 

class TableFactory 
{ 
    Table BuildTable(name) <- builds a table object. 
} 

나는 데 문제가 BuildTable() 메서드 IQueryProvider과 IComObject을 만들고 이름을 통과해야한다는 것입니다. 나는 희망을 (내가 제대로 이해 경우) 서비스 로케이터 패턴하지만이 같은 것을 사용하는 경우 어떻게 구현 :

BuildTable(string name) 
{ 
    IQueryProvider provider = ServiceLocator.GetInstance<IQueryProvider>(); 
    IComObject comobject = ServiceLocator.GetInstance<IComObject>(); 
    Table tab = new Table(name,provider,comobject); 
    return tab; 
} 

을 그것은 지금은 만드는 ServiceLocator에 IQueryProvider 및 IComObject 모두 가지고해야한다는 의미 내 의존성을보고 테스트하기가 어렵습니다. 그래서 나는이 같은 개체 및 공장 무언가의 다른 유형을 만들 종속성 공장을 만들어 :

class DependencyFactory 
{ 
    Table BuildTable(string name) 
    { 
     //call other BuildMethods to create objects. 
     //return new Table. 
    } 

    //Other Build methods for things like IQueryProvider, IComObject. 
} 

가 나는 단지 내 서비스 로케이터에 DependencyFactory을 등록해야하고 단지 방법을 구축 호출합니다.

이 냄새가 좋지 않습니까?

내 첫 번째 BuildTable 메서드는 괜찮습니까, 아니면 관련이 있습니다.

답변

0

테스트를 더 쉽게하려면 의존성 삽입을 사용하여 종속 객체를 만드는 데 사용되는 팩토리를 제공 할 수 있습니다. 모든 유형의 객체에 대해 단일 팩토리에서이 방법을 선호합니다. 예를 들어, 테이블에 대한 TableFactory가있을 수 있습니다. 이것에는, 2 개의 생성자가 있습니다. 디폴트는 올바른 팩토리가 인스턴스화되도록 (듯이)하는 것이고, 또 다른 생성자는 의존하는 오브젝트 팩토리를 삽입 할 수 있도록 (듯이)하는 것입니다. 생산 코드에서는 첫 번째 코드를 사용하고 테스트에서는 두 번째 코드를 사용하십시오.

public class TableFactory 
{ 
     private ServiceLocator Locator { get; set; } 

     public TableFactory() : this(null) { } 

     public TableFactory(ServiceLocator locator) 
     { 
      this.Locator = locator ?? new ServiceLocator(); 
     } 

     public Table BuildTable(string name) 
     { 
      IQueryProvider provider = ServiceLocator.GetInstance<IQueryProvider>(); 
      IComObject comobject = ServiceLocator.GetInstance<IComObject>(); 
      return new Table(name,provider,comobject); 
     } 
} 

ServiceLocator 클래스와 비슷한 작업을 수행하지만 필요에 따라 IQueryProvider 및 IComObject 인스턴스를 삽입합니다.

매우 간단한 주입 유형입니다. 원하는 경우 구성 파일을 통해 제공된 종속 오브젝트의 기본 버전을 가질 수도 있습니다. 이 경우 기본 생성자 만 있고 속성 삽입을 사용하여 종속 객체를 제공 할 수 있습니다. 속성은 내부 가시성을 가진 setter로 표시되어 구성 클래스가 팩토리를 만들고 속성을 올바르게 설정할 수 있습니다. 그런 다음 InternalsVisibleTo를 사용하여 세터를 테스트에 사용할 수있게하고 같은 작업을 수행 할 수 있습니다.

+0

하지만 여전히 정말 볼 수 없다는 문제가 해결되지 않습니다

일반적인 DI 컨테이너는 내부 의존성. 그러나 다시 SDK 내부에 있으므로 필요한 유형을 알고 있습니다. 뭘 해야할지. –

0

서비스 로케이터는 설명하는 이유와 정확히 일치하지 않는 패턴으로 간주합니다. 정확하게 유형을 올바르게 사용하는 방법을 알아 내기가 어렵습니다. Service Locator 대신 DI (Dependency Injection)를 사용하는 것이 좋습니다. 예를 들면 (그러나 이에 국한되지 않음) 생성자 주입. described in this blog post과 같이 수동으로 처리하거나 DI 컨테이너에서 처리 할 수 ​​있습니다.

+0

가능한 한 DI를 사용하지만, 내 주요 문제는 사용하려는 모든 개체를 어디에서 어떻게 생성하는지입니다. 그래서 나는 factory 객체를 만들지 만, 그 factory 객체를 어디에서 생성할까요? –

+0

@ Nathan W : 짧은 대답은 : 필요할 때. 보다 복잡한 대답은 다음과 같습니다. 응용 프로그램 스택의 맨 위 (또는보기에 따라 루트). 모든 것을 하나로 묶는 곳. 위의 블로그 게시물에 설명되어있는 것처럼 수동으로 할 수도 있고 DI 컨테이너에서 직접 할 수도 있습니다 ... 여기 서클에서 조금 움직이고 있기 때문에 질문의 차원이있을 수 있습니다. 나는 실종됐다 ... –

+0

동의합니다. 기본적으로 루트 (또는 그 주변)에서 앱을 구성합니다. 나는 IoC가 "위의 매개 변수"라고 부르는 것을 들었습니다. 그리고 그것은 꽤 많이 있습니다 - 의존성 생성/주입은 다음 단계에서 구성됩니다. 서비스 탐지 패턴은 한 가지 의미에서 가난한 사람의 DI와 거의 같습니다. 나는 과거에 그것을 시도하고 숨겨진 종속성으로 인해 코드를 어렵게 만듭니다. 전용 IoC 컨테이너를 사용하는 경우 코드의 99 %는 존재 여부를 알지 못하지만 응용 프로그램을 구성하기가 쉽고 구성이 간단하고 마음의 모든 내용을 테스트 할 수 있습니다. –