2011-03-14 12 views
2

생성자 인수를 자식 클래스의 생성자에 전달하는 메서드를 찾으려고합니다. 이러한 개체는 변경할 수 없으므로 생성자 인수를 사용하는 것이 좋습니다.Ninject에서 생성자 생성자 상속

내가 발생했습니다 문제는 ConstructorArgument 아동 인스턴스 생성에 상속하지 않는다는 것입니다 다음과 같은 진술은 서로 호환되지 않습니다 :

_parsingProcessor = _kernel.Get<IParsingProcessor>(new ConstructorArgument("dataFilePath", dataFilePath); 

및 상속 ConstructorArgument을 얻을 수있는 방법 그래서

_parsingProcessor = _kernel.Get<IParsingProcessor>(new Parameter("dataFilePath", dataFilePath, true); 

하고, 언제 매개 변수 클래스를 새로운 것으로 이해할 수 있습니까?

+1

당신이하려는 일에 대해 더 많은 정보를 줄 수 있습니까? 자식에게 매개 변수를 전달할 수 있습니다. 그러나 대부분의 시나리오에서 이것이 최선의 해결책은 아닙니다. –

답변

3

예, 가능하지만 실제로 원하는 것은 아닙니다. 컨테이너가 실제로 자체 종속성을 인스턴스화하는 책임이 없다면 종속성 은 아마도이 생성자 인수를 공유해서는 안되며 단지 의미가 없습니다.

나는 당신이 무엇을하려고하는지 잘 알고 있으며 권장되는 접근법은 아래 예제와 같이 WhenInjectedInto 조건부 바인딩 구문을 사용하는 것입니다.

public class Hello : IHello 
{ 
    private readonly string name; 

    public Hello(string name) 
    { 
     this.name = name; 
    } 

    public void SayHello() 
    { 
     Console.WriteLine("Hello, {0}!", name); 
    } 
} 

이것은 누가 IHello을 요구하는지에 따라 수정하려는 생성자 인수를 취하는 클래스입니다. 의는이 지루한 컨테이너 클래스입니다 가정 해 봅시다 : 이제

public class MyApp : IApp 
{ 
    private readonly IHello hello; 

    public MyApp(IHello hello) 
    { 
     this.hello = hello; 
    } 

    public virtual void Run() 
    { 
     hello.SayHello(); 
     Console.ReadLine(); 
    } 
} 

, 여기 당신이 바인딩을 수행하는 방법은 다음과 같습니다

public class MainModule : NinjectModule 
{ 
    public override void Load() 
    { 
     Bind<IApp>().To<MyApp>(); 
     Bind<IHello>().To<Hello>() 
      .WithConstructorArgument("name", "Jim"); 
     Bind<IHello>().To<Hello>() 
      .WhenInjectedInto<MyApp>() 
      .WithConstructorArgument("name", "Bob"); 
    } 
} 

기본적으로 모든 않는 "짐"이어야 name을 말하는하고있다 바인딩 이 경우에는 Hello에 의해 요청되므로 대신 "Bob"이라는 이름이 지정됩니다. 당신이 절대적으로 당신이 진정으로 행동을 계단식 원하고이 것을 이해 특정 경우


매우 위험하고 부서지기 쉬운, 당신은 바인딩하는 방법을 사용하여 부정 행위를 할 수 있습니다. 우리가 지금 약간의 지정 목적을 위해 MyApp 클래스에 name 인수를 추가 한 것으로 가정하면, 바인딩은 다음과 같습니다

Bind<IHello>().ToMethod(ctx => 
    ctx.Kernel.Get<Hello>(ctx.Request.ParentContext.Parameters 
     .OfType<ConstructorArgument>() 
     .Where(c => c.Name == "name") 
     .First())); 

, 이것은 당신이하기 전에 원하는 것을 당신이 긍정적 있는지 확인하십시오하세요 그것. 쉽게 보일 수 있지만 간단한 리팩토링 중에도 깨질 가능성이 매우 높습니다. 본인이 본 "맞춤 종속성"시나리오의 95 %는 WhenInjectedInto 바인딩을 대신 사용하여 해결할 수 있습니다.