3

저는 Ninject 및 Dependency Injection을 처음 사용하기 때문에 여기에 제 의견을 남겨주세요. =)Ninject : 클라이언트의 어셈블리를 생성자 인수로 전달하고 클라이언트에서 속성을 사용하여 원하는 구현을 지정합니다.

IConfigOption 인터페이스를 구현하는 유형에 대해 어셈블리와 그 의존성을 검사하는 IConfig 인터페이스의 여러 구현이 있습니다. 각 IConfig 구현은 서로 다른 출처에서 값을 검색합니다.

이러한 구현은 생성자 인수로 검색을 시작할 위치에서 루트 어셈블리를 가져오고 이러한 값을 삽입하는 바인딩을 제안하려고합니다. 지금까지 내가의 라인에 뭔가 생각하고 있어요 :

Bind<IConfig>().To<Config>().WithConstructorArgument("rootAssembly", target); 

내 문제는, 내가 Config 클래스가 주입 될 것 target 어셈블리에 대한 참조를 얻을 수있는 방법을 찾을 수 없습니다. DI가 없다면 Assembly.GetCallingAssembly()을 사용 하겠지만, 여기서는 바인딩이있는 어셈블리를 생성하고 원하는대로 대상 어셈블리를 생성하지 않습니다. 즉, 예를 들어, 클라이언트 클래스 A가 RoleEnvironment 및 클라이언트 클래스 B가 요청 이용하는 Config 구현 요청 그럼에도

, 난 주입 수신처 클래스/부재로부터 의도 구현 을 지정하는 방법이 필요 ConfigurationManager을 사용하는 Config 구현 자. 다음은 사용 목적 명확히하는 예입니다 :

public class Client 
{ 
    [UseApplicationConfig] 
    public IHelper WithAppConfig { get; set; } 

    [UseRoleEnvironmentConfig] 
    public IHelper WithRoleEnvironmentConfig { get; set; } 
} 

public class Helper : IHelper 
{ 
    public Helper(IConfig config) 
    { 
    } 
} 

나도 내가 잘못 각도에서이 찾고 있어요 아니면 내가 명백한 누락하는 느낌을 얻을,하지만 난 내가해야 모르겠어요 찾고. 어떻게 최선의 방법이 될까요?

대단히 감사합니다.

편집 : 명확한 설명을 위해 의도 된 사용 예를 추가하고 질문의 일부를 다시 표현했습니다.

답변

1

개체에 대한 요청에 대한 자세한 내용을 보려면 오버로드 WithConstructorArgument(string, Func<IContext, object>)을 사용하십시오. 제공된 IContext을 사용하여 어셈블리 이름을 찾을 수 있습니다 (둘러보기 위해 디버거를 사용하면 레이아웃이 복잡하여 특정 코드를 제공 할 수없는 것 같습니다). 이를 사용하는 방법의 예로서

:

//get the full name of the requested object 
Bind<IFoo>() 
    .To<Foo>() 
    .WithConstructorArgument("bar", 
          c => c.Request.FullName); 

그러나, 당신이 잘못된 각도에서 그것을보고있는 것처럼 나에게 들린다. 질문을 올바르게 읽으면 어셈블리를 스캔 한 다음 Ninject가 대신 수행 할 작업을 결정하는 클래스가있는 것처럼 들립니다. 나는 이것이 DI를 사용하지 않았을 때 남은 것이라고 생각합니까?

WhenInjectedInto 메서드 또는 사용자 지정 특성을 사용하여 컨텍스트 바인딩을 사용하여 생성자에 특정 IHelper을 삽입하는 방법을 살펴 보겠습니다.여기를 참조하십시오 : https://github.com/ninject/ninject/wiki/Contextual-Binding 링크 된 페이지가 실제로 당신을 위해 작동 할 수 비슷한 일을 예를 들어이

:

Bind<IWarrior>() 
    .To<Samurai>() 
    .When(request => request.Target.Type.Namespace.StartsWith("Samurais.Climbing")); 

아마 여전히 WhenInjectedInto를 사용하는 것 또는 그래서 당신은 "어떤이없는 불구 속성 마법의 문자열 "을 사용하여 나중에 네임 스페이스를 리팩터링 할 수 있습니다.

+0

그 클래스는'IConfigOption'의 구현자를 스캔하고 컬렉션에 추가합니다. 아무것도 삽입하지 않습니다. 나는 당신이 언급 한 해결책에 대해 생각했다. 문제는 상황에 구애받지 않아야한다는 것입니다. 따라서 수동으로 누가 이름이나 유형으로 주입을 요청했는지 확인하는 것은 옵션이 아니므로 구현 방법을 알고 있다면 속성을 사용하는 것이 더 나은 방법이라고 생각한 것입니다. (나는 아직도 잘못된 각도에서 이것을보고있을 것입니다.) 어쨌든, 답장을 보내 주셔서 감사합니다. 나는이 질문에 거의 희망을 포기했습니다. :) –

+0

나는 그것을 정확하게했고, 나는 그 어셈블리가 정확히 당신이 지적한 곳이라고 생각합니다. 그러나, 주입해야 할 클래스가 아니라 주입 할 클래스가있는 것은 어셈블리였습니다. 어떻게 든 원래의 상황을 잃어 버리는 것과 관련이 있다고 생각합니다 (지금은 세부 사항을 기억할 수 없습니다). 나는 ContextPreservation 플러그인을 시도해 보았지만 타겟 어셈블리를 어디에서도 찾을 수 없었지만, 커널 생성기 ()을 실행할 때만 발생했으며 생성자 주입을 사용할 때는 발생하지 않았습니다. 실제로 작동 한 방법 중 하나. 꽤 이상한. –