2017-01-25 1 views
1

같은 클래스에 서로 다른 인터페이스의 구현을 바인딩하지만 잠시이 이해하는 내 머리를 긁적했습니다 :Ninject에 - 나는 DI (Ninject에 사용) 새로운 단지 개념을 배우기 시작 해요

을 내 프로그램에서 같은 클래스의 다른 사용법을 사용한다고 가정 해 봅시다 (아래 예에서 ProcessContext).

첫 번째 클래스에서 (SomeClass) : 을 ProcessContext 인스턴스에 삽입하고 싶습니다.

두 번째 클래스에서 (SomeOtherClass) : 을 ProcessContext 인스턴스에 삽입하고 싶습니다.

Ninject를 사용하여 바인딩을 어떻게 수행해야합니까?

public class Implement1 : IAmInterace 
{ 
    public void Method() 
    { 
    } 
} 

public class Implement2 : IAmInterace 
{ 
    public void Method() 
    { 
    } 
} 

public class ProcessContext : IProcessContext 
{ 
    IAmInterface iamInterface; 
    public ProcessContext(IAmInterface iamInterface) 
    { 
     this.iamInterface = iamInterface; 
    } 
} 

public class SomeClass : ISomeClass 
{ 
    public void SomeMethod() 
    { 
     // HERE I WANT TO USE: processcontext instance with Implement1 
     IProcessContext pc = kernel.Get<IProcessContext>();    
    } 
} 

public class SomeOtherClass : ISomeOtherClass 
{ 
    public void SomeMethod() 
    { 
     // HERE I WANT TO USE: processcontext instance with Implement2 
     IProcessContext pc = kernel.Get<IProcessContext>();    
    } 
} 
+0

매개 변수를 기반으로 구현을 선택할 수있는 [전략 패턴] (http://stackoverflow.com/a/32415954/181087)과 같은 것이 필요한 것 같습니다. 여기에 또 다른 [예제] (http://stackoverflow.com/a/31971691/181087)가 있는데, 같은 패턴을 추상 팩토리와 결합하여 인스턴스를 즉시 가져옵니다. – NightOwl888

답변

0

이 경우 named bindings을 사용할 수 있습니다.

Bind<IProcessContext>() 
    .To<ProcessContext>() 
    .WithConstructorArgument("iamInterface", context => Kernel.Get<Implement1>()) 
    .Named("Imp1"); 

Bind<IProcessContext>() 
    .To<ProcessContext>() 
    .WithConstructorArgument("iamInterface", context => Kernel.Get<Implement2>()) 
    .Named("Imp2"); 

kernel.Get<IProcessContext>("Imp1"); 
+0

감사합니다! SimpleInjector로 어떻게 수행하는지 더 자세히 설명 할 수 있습니까? – ohadinho

+1

@ohadinho 죄송합니다. SimpleInjector에 대한 경험이 없습니다. 해당 라이브러리에 대한 새로운 질문을 시작해야합니다. –

+0

SimpleInjector에서 contextbasedinjection을 발견했습니다 : http://simpleinjector.readthedocs.io/en/latest/advanced.html#context-based-injection – ohadinho

0

이 방법으로 쉽게 추가 생성자 매개 변수를 삽입 할 수 있습니다 지금은

public void SomeMethod() 
{ 
    var foo = new Ninject.Parameters.ConstructorArgument("iamInterface", new Implement2()); 
    IProcessContext pc = kernel.Get<IProcessContext>(foo);    
} 

, 나는 ninject에 액세스 할 수 없습니다. 그래서 그것이 예상대로 작동하지 않으면 말해봐.

+0

필자의 예에서는 2 개의 인터페이스 만 사용했습니다. "foo"는 같은 문제가 발생합니까? Implement2가 생성자에서 IAmInterface2를 얻으면 다시 ConstructorArgument를 설정해야합니다. 쉬운 방법이 없습니까 ?? – ohadinho

+0

@ohadinho 귀하의 경우에 당신은 구체적인 유형을'IProcessContext'에 전달하고자합니다. 실제로 DI 컨테이너를 사용하고 싶지는 않습니다. 그러나 만약'Implement2'가 다른 인터페이스를 필요로한다면 여러분은 필요한 인수를 주입해야합니다. 나는 보통 당신이'Ninject' 자체로부터 인스턴스를 얻고'Ninject'가 그것에 매개 변수를 전달하도록합니다. – Feriloo

0

Ninject는 반환 할 구현을 알 수 없으므로 불가능합니다. 하나; 변수를 전달하여 IProcessContext의 새로운 인스턴스를 생성하면 Ninject는 해당 생성자를 사용하여 구현을 찾고 반환합니다.