2010-02-15 4 views
4

나는 인스턴스화하고 반환해야하는 4 개의 서브 클래스 중 어느 것을 결정하는 팩토리 클래스를 가지고있다. 여러분이 기대하고있는 바와 같이, 모든 서브 클래스는 같은 인터페이스를 구현 :IoC를 통해 팩토리 클래스에 종속성을 제공합니까?

public static class FooFactory{ 
    public IFoo CreateFoo(FooEnum enum){ 
      switch (enum) 
      { 
       case Foo1: 
        return new Foo1(); 
       case Foo2: 
        return new Foo2(); 
       case Foo3: 
        return new Foo3(IBar);//has a constructor dependency on IBar 
       case Foo4: 
        return new Foo4(); 
       default: 
        throw new Exception("invalid foo!"); 
      } 
    } 
} 

당신이 볼 수 있듯이이, 서브 클래스 중 하나가 생성자에 정의 된 종속성이 있습니다. 관심의

몇 가지 포인트 :

  • 우리는 우리의 IoC로 Spring.NET을 사용하고 있습니다.
  • IFoo의 모든 하위 클래스는 도메인 객체이므로 Spring.NET에서 인스턴스화하지 않습니다. 가능한 한 이런 식으로 유지하고 싶습니다.
  • 응용 프로그램에는 손으로 작성된 데이터 액세스 레이어 (토큰)가 있으므로 여기에 ORM이 없습니다.

내가 가장 FooFactory에서 Foo3IBar 의존성을 전달하는 방법을 알아 내려고 노력하고있어. 나는 이것이 IoC를 통해 가장 잘 해결되는 문제 일지 모른다는 느낌을 얻지 만, 나는 어떻게 그럴 수 없는가. 또한 FooFactory을 가능한 한 테스트 할 수있는 단위로 유지하고 싶습니다. 즉, 테스트 코드에서 Spring.NET에 대한 의존성을 가질 필요가 없다는 것을 선호합니다.

읽어 주셔서 감사합니다.

+1

내가 삼촌 밥 그냥이 주제에 대한 악명 게시물을 것 같아요. http://davybrion.com/blog/2010/01/dependency-injection-inversion-rejection/ –

답변

6

변경 FooFactory 추상 공장와 같이, 구체적인 구현에 IBar 인스턴스를 주입 :

FooFactory가 IFooFactory 인터페이스를 구현하는 콘크리트, 비 정적 클래스는 지금이다
public class FooFactory : IFooFactory { 
    private readonly IBar bar; 

    public FooFactory(IBar bar) 
    { 
     if (bar == null) 
     { 
      throw new ArgumentNullException("bar"); 
     } 

     this.bar = bar; 
    } 

    public IFoo CreateFoo(FooEnum enum){ 
      switch (enum) 
      { 
       case Foo1: 
        return new Foo1(); 
       case Foo2: 
        return new Foo2(); 
       case Foo3: 
        return new Foo3(this.bar); 
       case Foo4: 
        return new Foo4(); 
       default: 
        throw new Exception("invalid foo!"); 
      } 
    } 
} 

주의 사항 :

public interface IFooFactory 
{ 
    IFoo CreateFoo(FooEnum emum); 
} 

IFoo 인스턴스가 필요한 모든 곳에서 코드에 IFooFactory를 종속시키고 CreateFoo 메서드를 사용하여 필요한 인스턴스를 만듭니다.

FooFactory와 그 의존성을 염분이있는 DI 컨테이너를 사용하여 연결시킬 수 있습니다.

+0

좋아, 나는 전략을보고, 내가 본 것을지지하면서, 내가 말한 것을지지한다. 내가 놓친 게 있니? 나는 IOC를 구현하기 위해 제안하지 않았으며, 그가 공장에서 IOC를 사용하는 것을 피할 필요가 없다. 유효한 코드를 붙여 넣으면 +1하십시오. –

+2

@ 샌디 샌더스 : DI 컨테이너가 공장에있는 것을 피하는 것이 좋습니다. 팩토리는 다른 것과 마찬가지로 도메인 객체이며 도메인 객체 안에 컨테이너를 가지고 있으면 서비스 탐지기가 패턴을 벗어납니다 : http://blog.ploeh.dk/2010/02/03/ServiceLocatorIsAnAntiPattern.aspx –

+0

삼촌 밥에게 말해. 롤. 고마워, 내가 읽고있어 ... –

0

당신도 케이크를 먹고 그것을 먹는 것처럼 들립니다. 당신은 IOC 전략에 전념해야합니다.

당신은 betta의 코드 개월을 생산하고 새끼보다 너무 .... 당신을 파고 것이다 페이지

+0

@Sky Sanders, 나는 당신이 놀고있는 병아리에 대해 확신하지 못하지만, IoC 전략을 저 지르면 그들 중 누구라도 더 많이 파고들 것입니다. –

+0

특정 DI 컨테이너에 커밋 할 필요가 없습니다 가장 최근 순간까지 : http://stackoverflow.com/questions/2045904/dependency-inject-di-friendly-library/2047657#2047657 –

+0

제 문제 중 일부는 공장 및 Inversion of Control 패턴이 Dependecy Injection continuum. 아마도 당신은보다 계몽적인 반응을 제공 할 수 있습니까? –

관련 문제