2016-11-26 9 views
2
여기

은 내가하고 싶은 것입니다 :Ninject를 사용하여 명시 적으로 구현 된 메소드에 주입 할 수 있습니까?

public interface IInject<in T> 
{ 
    [Inject] 
    void Inject(T reference); 
} 

private class Foo : IInject<Bar> 
{ 
    public Bar Bar { get; private set; } 

    void IInject<Bar>.Inject(Bar reference) 
    { 
     Bar = reference; 
    } 
} 

을하지만 아무것도 주입하지 도착, 유일한 방법은 내가 직장에 도착 그 속성 및 암시 적 구현입니다 :

private class Foo : IInject<Bar> 
{ 
    public Bar Bar { get; private set; } 

    [Inject] 
    public void Inject(Bar reference) 
    { 
     Bar = reference; 
    } 
} 

할 수있는 방법이 있나요 그것?

+0

질문에서 빠진 것은 * 왜 * 당신이 이것을하고 싶은지입니다. 메소드 주입은 일반적으로 [시간 결합] (http://blog.ploeh.dk/2011/05/24/DesignSmellTemporalCoupling/)으로 연결되기 때문에 좋은 생각이 아닙니다. – Steven

+1

@Steven 동의 회원 가입은 불쾌합니다. 사이클 때문에 IoC에 친숙하지 않은 털이 많은 그래프를 물려 받았습니다. 이렇게하면 디자인을 좀 더 멋지게 리팩터링하는 동안 일시적인 것일뿐입니다. –

답변

2

Ninject는 기본적으로 동작하지 않습니다. 사용자 지정 선택기를 만들어야합니다. *

당신의 유형을 감안할 때,이 선택은 당신이 설명한 동작,

class ExplicitSelector : Selector 
{ 
    public ExplicitSelector(
     IConstructorScorer constructorScorer, 
     IEnumerable<IInjectionHeuristic> injectionHeuristics) 
     : base(constructorScorer, injectionHeuristics) 
    { 
    } 

    public override IEnumerable<MethodInfo> SelectMethodsForInjection(Type type) 
    { 
     // Gets all implemented interface and grabs an InterfaceMapping. 
     var implementedInterfaces = type.GetInterfaces(); 

     foreach (var map in implementedInterfaces.Select(type.GetInterfaceMap)) 
     { 
      for (var i = 0; i < map.InterfaceMethods.Length; i++) 
      { 
       // Check each interface method for the Inject attribute, and if present 
       if (map.InterfaceMethods[i].CustomAttributes.Any(x => x.AttributeType == typeof (InjectAttribute))) 
       { 
        // return the target method implementing the interface method. 
        yield return map.TargetMethods[i]; 
       } 
      } 
     } 

     // Defer to NInject's implementation for other bindings. 
     foreach (var mi in base.SelectMethodsForInjection(type)) 
     { 
      yield return mi; 
     } 
    } 
} 

그것은 단순히 커널에 추가되는,

standardKernel.Components.Remove<ISelector, Selector>(); 
standardKernel.Components.Add<ISelector, ExplicitSelector>(); 

그리고 전시 IInject<Bar>을 얻으려면 사용자 정의 선택기를 사용하여 설명하는대로 작동합니다.


* 는 Ninject에와이를 구현하는 더 나은 확장 점이있을 수 있습니다. 나는 NInject 또는 그것의 구현에 대한 전문가와는 거리가 멀다.