23

마침내 필자는 의존성 주입 (Dependency Injection)과 함께 젖었습니다. Unity와 함께 게임을 시작했고 전략 패턴에 문제가 생겼습니다. 컨테이너를 사용하여 이름을 기반으로 한 특정 전략의 구현을 반환 할 수 있지만, 내가 볼 수없는 것은 컨텍스트에서 올바른 전략을 얻는 방법입니다.
간단한 예를 들어 설명해 보겠습니다. 컨텍스트는 FastEngine과 SlowEngine이라는 두 가지 구현을 가진 IEngine (전략)이있는 자동차입니다. 코드는이 라인을 따라 보일 것이다유니티를 사용한 전략 패턴 및 의존성 삽입

public interface IEngine 
{ 
    double MaxSpeed 
    { 
     get; 
    } 
} 

internal class FastEngine:IEngine 
{ 
    public double MaxSpeed 
    { 
     get 
     { 
      return 100d; 
     } 
    } 
} 

internal class SlowEngine:IEngine 
{ 
    public double MaxSpeed 
    { 
     get 
     { 
      return 10d; 
     } 
    } 
} 

public class Car 
{ 
    private IEngine engine; 
    public double MaximumSpeed 
    { 
     get 
     { 
      return this.engine.MaxSpeed; 
     } 
    } 

    public Car(IEngine engine) 
    { 
     this.engine = engine; 
    } 
} 

내 문제는 다음과 같은 : 나는 빠른 자동차 또는 느린 차를 인스턴스화에 대해 어떻게 가야하나요? 나는 각 구현 나를 제공하기 위해 컨테이너를 사용할 수 있으며, 내가 사용하는 "기본"구현을 설정할 수 있습니다

IUnityContainer container = new UnityContainer(); 
container.RegisterType<IEngine, FastEngine>(); 
container.RegisterType<IEngine, FastEngine>("Fast"); 
container.RegisterType<IEngine, SlowEngine>("Slow"); 
var car = container.Resolve<Car>(); 
Assert.AreEqual(100, car.MaximumSpeed); 

을하지만 내가 원하는 것은 특정 구현 자동차를 요청 할 수있다 전략 - 비슷한 것

var car = container.Resolve<Car>(??? use "Fast" or "Slow ???); 

컨테이너를 사용해도됩니까? 아니면 컨테이너를 사용하는 공장을 작성해야합니까? 어떤 지침이라도 고맙게 여길 것입니다 - 나는 이것에 대해 올바르게 생각하고 있는지 확신하지 못합니다!

답변

26

DI의 일반적인 패턴은 실행시에서 인데 주어진 추상화의 단일 구현 일뿐입니다. 그것은 당신이 묘사하는 것과 같은 모호성을 다룰 필요가 없기 때문에 인생을 훨씬 쉽게 만듭니다.

그러나 때로는 예제와 같이 상황에 따라 구현을 변경해야합니다. 많은 DI 컨테이너는 적합한 매개 변수를 제공 할 수있는 방법을 제공하지만 이는 결국 특정 DI 컨테이너에 코드를 단단히 묶어 버릴 수 있음을 의미합니다.

더 나은 해결책은 필요한 것을 제공 할 수있는 Abstract Factory을 소개하는 것입니다.

public interface ICarFactory 
{ 
    Car Create(IEngine engine); 
} 

더 많은 전략을 주입해야하는 경우

같은 무언가가, 아마도 Builder 디자인 패턴은 더 나은 적합 있습니다.

모든 경우에 컨테이너에 다른 Cars를 많이 등록하는 대신 하나의 ICarFactory 구현을 등록하는 것이 중요합니다.

클라이언트 코드에서 삽입 된 ICarFactory를 사용하여 특정 IEngine을 기반으로 Car 인스턴스를 만들 수 있습니다.

var car = factory.Create(engine); 
+0

감사합니다. 통찰력있는 답변. 나는 여러 전략을 런타임에 바꿔 놓은 전략 패턴을 사용한다. 기본적으로 당신이 설명하는 것을 할 것입니다 (공장 또는 빌더). 그러나 전략 패턴과 DI가 많이 관련되어 있음을 알았지 만 이것이 도움이 될 수 있습니다. 당신이 말한 것에서 볼 때, 컨테이너는 단지 약간 도움이되는 것처럼 보입니다. – Mathias

+0

나는 아직도 용기가 매우 도움이된다고 생각한다. 이 경우, 그들은 전략 대신에 단지 공장을 주입 할 것이지만, 당신은 여전히 ​​컨테이너로 공장을 구현할 수 있다고 생각합니다. –

+4

오, 당신이 무슨 뜻인지 알 것 같아요. 올바른 차를 반환하기보다는 엔진을 기반으로 올바른 공장을 반환하십시오. 어쨌든 귀하의 의견은 추상화를위한 단일 구현을 제공하는 데 사용 된 컨테이너가 매우 유용했습니다. 그것은 내가 본 구성 예제와 일치합니다. 이 프레임에는 전략 패턴이있을 수 있지만 특정 배포에는 구현이 하나만 구성됩니다. – Mathias