2008-11-11 2 views
9

저는 이것이 IoC 컨테이너를 사용하기 시작한 것이므로 어리석은 질문 인 경우 사과드립니다.IoC 컨테이너가 공장의 사용을 대체합니까

나는 응용 프로그램

internal static class StaticDataHandlerFactory 
    { 
     public static IStaticDataHandler CreateHandler(StaticDataUpdate staticDataUpdate) 
     { 
      if (staticDataUpdate.Item is StaticDataUpdateOffice) 
      { 
       return new OfficeUpdateHandler(); 
      } 

      if (staticDataUpdate.Item is StaticDataUpdateEmployee) 
      { 
       return new EmployeeUpdateHandler(); 
      } 

      if (staticDataUpdate.Item == null) 
      { 
       throw new NotImplementedException(
        string.Format("No static data provided")); 
      } 
      else 
      { 
       throw new NotImplementedException(
        string.Format("Unimplemented static data type of {0}", staticDataUpdate.Item.GetType().FullName)); 
      } 
     } 
    } 

그것은 기본적으로 입력 데이터를 처리하기위한 올바른 전략을 반환하는 간단한 공장에 다음과 같은 코드가 있습니다.

IoC 컨테이너를 사용하면 이와 같은 코드를 제거 할 수 있습니까? 즉, 입력 매개 변수의 유형에 따라로드 할 구체 구현을 동적으로 선택할 수 있습니까?

여기 또는 코스에서 벗어나나요?

답변

7

실제로 코드의 일부를 제어 시스템의 반전으로 대체 할 수는 있지만 좋은 아이디어는 아닙니다. 의존성 주입은 동적 인 객체 생성이 아닌 시스템 구성에 가장 적합합니다. 이를 다른 방식으로 표현하기 위해 컨테이너 자체는 거대한 전역 변수이므로 코드의 상당 부분에 나타나야합니다.

제쳐두고 코드는 Law of Demeter을 위반하는 것으로 보입니다. 매개 변수의 유형이 "StaticDataUpdate"가 아닌 "StaticDataUpdateItem"이어야합니다. 관찰 된 바에 따르면이 코드를 StaticDataUpdateItem의 메서드 호출로 다시 작성하는 것에 대한 매우 강력한 주장이 있습니다.

IoC를 상당히 많이 사용했지만 동적 객체 생성은 여전히 ​​추상 팩터 리 패턴을 사용하는 것이 더 좋습니다. 간단히 말해, 핸들을 생성하기 위해 항목 자체에 메소드를 추가하는 아이디어가 마음에 들지 않는다면 코드는 아마도 그대로 남겨 두는 것이 가장 좋습니다.

0

짧은 대답은 네입니다. 이 blog post은 Windsor를 사용하여 런타임에 구현을 선택하는 매끄러운 방법을 보여줍니다. 저자 Ayende는 herehere을 자세히 설명합니다.

아직 시도하지는 않았지만 곧 기대됩니다.

2

당신은 전혀 멀지 않습니다. 내가 이해하는 방식으로, 당신은 꽤 가깝습니다.

가장 일반적으로 이런 종류의 구조를 만드는 방법은 종속성 삽입을 사용하여 지정되도록 반환 된 UpdateHandler를 허용하여 Factory 클래스를 IoC 컨테이너로 변환하는 것입니다. 따라서 코드에서 StaticDataUpdateOffice가 OfficeUpdateHandler를 반환한다는 것을 지정하는 논리 대신에 StaticallyDataUpdateOffice가 (새로 지정된) m_officeUpdateHandler 변수에 포함 된 값을 반환한다는 코드로 전환 할 수 있습니다. 공장을 호출하기 전에 Framework에서 m_officeUpdateHandler의 값을 설정하면 작업을 수행하는 것이 좋습니다. 필요에 따라 런타임에 원하는 값으로 m_officeUpdateHandler의 값을 변경할 수 있습니다.

이 종속성 삽입을 사용하면 Inversion of Control 프로세스를 제어 할 수 있습니다. 핸들러를 리턴하는 간단한 팩토리를 가질 수 있으며, 핸들러가 다른 위치로 리턴되는 것을 제어하는 ​​로직을 적절하게 추상화 할 수 있습니다.

참고 : 이런 종류의 경험은 Spring에 대한 저의 (매우 긍정적 인) 경험에 의해 강력하게 이끌어 지므로 여러분의 질문 (및 대답)에 대한 나의 해석이 색칠 될 수 있습니다.

0

다른 답변에 동의합니다. 그렇습니다. 그렇게 할 수 있습니다. 하지만 제네릭을 사용하지 않으시겠습니까?

public static IStaticDataHandler CreateHandler<T>(params object[] args) 
{... 

여기서 args는 ctor 인수 (예 : Activator)로 전달 될 수 있습니다.

+1

제네릭은 컴파일 시간에 해결 얻을 때문에 - 그는화물, 런타임 결정으로 실시되고있는 항목의 종류에 따라 자신의 결정을 만들고있다. – Bevan

+1

컴파일시 제네릭을 해결할 필요는 없습니다. 나를 믿지 않으면 Type.MakeGenericType()을보십시오. – dviljoen

-2

나는이 단어를 읽지 않고 아직별로 의미가 없다.

IoC는 config에 더 적합합니까?

동적 개체 생성이 더 좋을까요? 제네릭? 이것은 모두 주제에서 벗어난 것입니다.

1) IoC는 '전문화/상속을 통한 구성'복음을 구현하는 것에 비해 시간을 절약하는 데 그치는 것이 아닙니다.

그래서 IoC를 사용하는 규칙 # 1은 '구현하지 않는 계약으로 바인딩'을 따르는 긴 생성자를 처리해야한다는 것에 지쳐 있어야합니다.

다른 말로하면, 이것은 같은 이유로 (encapsulate ...) 템플리트 패턴을 대체 할 수있는 대안 적 패턴입니다 ... 그러나 모든 여분의 인터페이스/추상 유형을 작성하는 것이 더 많은 작업이며 ..

그러나

IInterestingService 흥미로운 = ... 당신이 얻을 인스턴스 : 더 많은 작업은 지루하게 같은 코드 계약을 이행하는 데 피곤하지 않은 경우 모든 IServiceProvicerThis 및 IResolverThat ... 그것을마다 할 일

다음과 같이 약 3 줄을 더 추가하십시오.

다음(210)

IAmazementService 서비스 = 새로운 AmazementService (흥미, thesecondstrategy, thethird 등) 낡았

. 그래서 IoC는 절대 의문의 대상이 아닙니다. 솔리드 한 디자인을 사용하여 코드를 작성할 수있을만큼 똑똑한 사람이라면 더 잘 알 수 있기 때문입니다. 묻는 사람들은 모든 잘못된 대답을 가지고 있습니다.

그럼 실제로 위의 사항을 절대적으로 충족하는 경우. IoC 컨테이너는 처리에 도움이되는만큼 많은 '창조적 인'작업을 수행 할 수 있습니다. 그리고 명백한 새로운 것에 대한 가장 일반적인 창조적 인 맹점은 Mr. Factory입니다.

데이먼

관련 문제