2016-11-26 71 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的專家或者它的實現。

相關問題