2017-02-15 4 views
0

생성자를 가져 오는 클래스를 등록하기 위해 컨테이너를 설정하려고합니다. IoC에서 이름이 지정된 인스턴스를 가져 오는 방법을 알고 싶습니다 (해당 기능을 사용할 수있는 경우). 시). 예를 들어 내가 이루고자하는 목표는 다음과 같습니다.SimpleInjector 사전을 생성자 인수로 사용합니다.

container.Register<IOtherInterface>(() => 
    new OtherInterface(new Dictionary<string, IInterface> 
    { 
     { "a", container.GetInstance<IInterface>("named-a") }, 
     { "b", container.GetInstance<IInterface>("named-b") }, 
    }); 

구성 방법이 있습니까?

업데이트 : 인터페이스의

구현은 다른 매개 변수를 객체와 동일하고 내가 SI 문서 https://simpleinjector.readthedocs.io/en/latest/howto.html#resolve-instances-by-key에서 볼 수 없었던 예입니다. 나는 새로운 인터페이스를 인스턴스화해야한다는 사실을 피하고 싶다. (.. 관련 매개 변수와 함께 ...) 사전에있는 각 값에 대해 등록을 명명하는 것이 SI에서 사용할 수있는 것이라고 생각한 이유이다.

내 접근 방식이 잘못되었을 수 있으며 다른 방식으로 종속성을 설정해야합니다. 사용의

예 :

public class OtherInterface : IOtherInterface 
{ 
    private readonly IDictionary<string, IInterface> _interfces; 

    public OtherInterface(IDictionary<string, IInterface> interfaces) 
    { 
     _interfaces = interfaces; 
    } 

    public void DoSomething(MyRequest request) 
    { 
     if(_interfaces.ContainKey(request.SelectMyInterface)) 
     { 
      _interfaces[request.SelectMyInterface].DoSpecificStuff(); 
     } 
    } 
} 

나는 잠재적 인터페이스는 IInterface를 확장하고 Applies(string type) 같은 방법을 가지고 여기에 전략 패턴을 적용하지만 Ninject에와 과거에 사전 접근 방식을 사용했을 수 있습니다.

+0

키가있는 등록, 사전 및 공장 [여기] (https://simpleinjector.readthedocs.io/en/latest/howto.html#resolve-instances-by-key)에 대한 매우 광범위한 문서가 있습니다. 이 문서가 귀하의 질문에 대한 답변을 제공하지 않는 경우 귀하의 질문에 대한 자세한 내용을 업데이트하십시오 (귀하의 질문이 변경되었음을 독자에게 알리기 위해 의견을 게시하는 것을 잊지 마십시오). – Steven

+0

실제 시나리오로 업데이트되었습니다. 나는 이미 키 입력에 대해서 읽었으나이 특별한 경우와 관련된 것을 찾을 수 없다. –

+0

'OtherInterface'가'named-a' 나'named-b'를 언제 사용하는지 어떻게 결정합니까? 'a'와'b' 키를 어떻게 결정합니까? – Steven

답변

1

키 입력 등록이 만들어 간단한 인젝터에 완료 InstanceProducer 경우 다음과 같이 '수동'

var a = Lifestyle.Transient.CreateProducer<IInterface, A>(container); 
var b = Lifestyle.Transient.CreateProducer<IInterface, B>(container); 

이 인스턴스 생산자를 사용하여 다음과 같이, 당신은 사전 등록을 할 수 있습니다 :

container.Register<Dictionary<string, IInterface>(() => new Dictionary<string, IInterface> 
{ 
    { "a", a.GetInstance() }, 
    { "b", b.GetInstance() }, 
}); 

당신의 OtherInterface은 나에게 발송자처럼 보입니다. 들어오는 요청을 라우팅하는 것이 유일한 일이라면 나는 괜찮다고 말할 것입니다.

하지만 그 대신 생성 된 인스턴스의 전체 목록과 사전을 주입, 나는 조금 다른 디자인을 제안하고 싶습니다 :

public class OtherInterface : IOtherInterface 
{ 
    private readonly IDictionary<string, Func<IInterface>> _interfces; 

    public OtherInterface(IDictionary<string, Func<IInterface>> interfaces) { 
     _interfaces = interfaces; 
    } 

    public void DoSomething(MyRequest request) => 
     _interfaces[request.SelectMyInterface].Invoke().DoSpecificStuff(); 
} 

여기에 사전에 Func<IInterface>이 포함되어 있습니다. 모든 호출에서 모든 구현을 작성할 필요없이 구현을 즉석에서 작성할 수 있습니다.

container.RegisterSingleton<IOtherInterface>(new OtherInterface(
    new Dictionary<string, Func<IInterface>> 
    { 
     { "a", CreateProducer<A>() }, 
     { "b", CreateProducer<B>() }, 
    }); 

private Func<IInterface> CreateProducer<T>() where T : IInterface => 
    Lifestyle.Transient.CreateProducer<IInterface, T>(this.container).GetInstance; 

를 다른 방법으로는 제한된 양의로 말할 조금 어려운 있지만, here 설명 (더 자세히 here 설명) 당신은 디자인에서 혜택을 누릴 수, 다음과 같이

이 작업을 등록 할 수 있습니다 귀하의 질문에 의해 주어진 문맥.

+0

Func 접근 방식이 마음에 듭니다! OtherInterface가 LifeStyle.Singleton을 가지므로 모든 인스턴스가 응용 프로그램이 부트 스트랩되는 경우에만 생성 될 것이라고 가정합니다. –

+0

@CarlosTorrecillas :'Func '이 각 호출에서 콜을 컨테이너로 다시 전송하기 때문에'OtherInterface'가 * Singleton *인지 여부는이 경우에 부적합합니다. 즉, 'OtherInterface'가 * Singleton * 인 경우에도 팩토리 인스턴스의 라이프 스타일은 보존됩니다. – Steven

+0

설명해 주셔서 감사합니다. –

관련 문제