2016-07-11 41 views
2

Wir haben ein Multi-Bindung in einem NinjectModule für einige IInspection Schnittstelle definiert, wie folgt aus:Zugriff auf eine erweiterte Schnittstelle auf einem Interceptor?

private void BindCodeInspectionTypes() 
{ 
    var inspections = Assembly.GetExecutingAssembly() 
           .GetTypes() 
           .Where(type => type.BaseType == typeof (InspectionBase)); 

    // multibinding for IEnumerable<IInspection> dependency 
    foreach (var inspection in inspections) 
    { 
     var binding = Bind<IInspection>().To(inspection).InSingletonScope(); 
     binding.Intercept().With<TimedCallLoggerInterceptor>(); 
     binding.Intercept().With<EnumerableCounterInterceptor<InspectionResultBase>>(); 
    } 
} 

So sind die Abfangjäger Proxy-Typen für IInspection sein wird. Doch einige der inspection Typen eine IParseTreeInspection Schnittstelle implementieren, die erstrecktIInspection:

public interface IParseTreeInspection : IInspection 
{ 
    ParseTreeResults ParseTreeResults { get; set; } 
} 

Das Problem das schafft mit diesem Stück Code ist, der den Abfangjäger verbraucht - die injizierten Proxy-Typen verständlicherweise scheinen nicht zu wissen, etwas über IParseTreeInspection, so dass diese foreach Schleife iterieren nicht einmal einmal:

var enabledParseTreeInspections = _inspections.Where(inspection => 
    inspection.Severity != CodeInspectionSeverity.DoNotShow 
&& inspection is IParseTreeInspection); 

foreach (var parseTreeInspection in enabledParseTreeInspections) 
{ 
    (parseTreeInspection as IParseTreeInspection).ParseTreeResults = parseTreeWalkResults; 
} 

gibt es eine Möglichkeit I-bind Multi IInspection (dh Konstruktor-Injectkann) und können immer noch IParseTreeInspection Instanzen erzählen, wenn Ninject Interzeptoren injiziert?

Antwort

0

Dies ist eine Möglichkeit, es zu tun:

foreach (var inspection in inspections) 
{ 
    if (typeof (IParseTreeInspection).IsAssignableFrom(inspection)) 
    { 
     var binding = Bind<IParseTreeInspection>() 
      .To(inspection) 
      .InSingletonScope() 
      .Named(inspection.FullName); 

     binding.Intercept().With<TimedCallLoggerInterceptor>(); 
     binding.Intercept().With<EnumerableCounterInterceptor<InspectionResultBase>>(); 

     Bind<IInspection>().ToMethod(
      c => c.Kernel.Get<IParseTreeInspection>(inspection.FullName)); 
    } 
    else 
    { 
     var binding = Bind<IInspection>().To(inspection).InSingletonScope(); 
     binding.Intercept().With<TimedCallLoggerInterceptor>(); 
     binding.Intercept().With<EnumerableCounterInterceptor<InspectionResultBase>>(); 
    } 
} 

Dieser Code prüft, ob der Typ von IParseTreeInspection zuordenbar ist, das heißt, es IParseTreeInspection implementiert, und wenn ja, schafft es eine benannte Bindung von IParseTreeInspection auf diese Art und konfiguriert das Interception hier. Dadurch wird sichergestellt, dass die Proxy-Objekte (erstellt vom Interceptor) IParseTreeInspection implementieren. Dann wird eine weitere Bindung von IInspection an einen Delegataufruf erstellt, der den Kernel dazu verwenden würde, IParseTreeInspection über die erste Bindung aufzulösen (unter Verwendung des Bindungsnamens).