2016-11-26 2 views
2

Hier ist, was würde ich tun:Ist es möglich, mit Ninject in eine explizit implementierte Methode zu injizieren?

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; 
    } 
} 

wird aber nichts injiziert, nur so, dass ich Arbeit habe ist mit dem Attribut und implizite Umsetzung:

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

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

Gibt es eine Möglichkeit zu tun es?

+0

Was von der Frage fehlt, ist * warum * du willst das tun. Method Injection ist in der Regel keine gute Idee, weil es zu [Temporal Coupling] führt (http://blog.ploeh.dk/2011/05/24/DesignSmellTemporalCoupling/). – Steven

+1

@Steven Vereinbarte Mitglied Injektion ist böse. Ich habe eine haarige Grafik geerbt, die aufgrund von Zyklen nicht IoC-freundlich ist. Dies ist hoffentlich nur vorübergehend, während das Design zu etwas Schönerem umgeformt wird. –

Antwort

2

Ninject verhält sich nicht standardmäßig so. Sie benötigen einen eigenen Selektor erstellen. *

Angesichts Ihrer Typen dieser Selektor zeigt das Verhalten, das Sie beschrieben haben,

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; 
     } 
    } 
} 

Es ist einfach zum Kernel,

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

Und dann Anrufe, um eine IInject<Bar> zu bekommen, wird funktionieren, wie Sie beschreiben, mit dem benutzerdefinierten Selektor.


* Es kann ein besserer Erweiterungspunkt sein, dies mit ninject zu implementieren. Ich bin weit entfernt von einem Experten für NInject oder dessen Implementierung.

Verwandte Themen