2016-11-26 101 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的专家或者它的实现。

相关问题