5

Ich beschreibe meine Umgebung: Ich habe Ninject + Ninject Interception Extension, um die automatische Registrierung von Interzeptoren für alle Methoden zu aktivieren, markiert mit einem speziellen Attribut. Dies ist ein gängiges AoP + -Attributs + DI-Containerszenario.Ninject Interception - brechende Änderungen bei der Portierung auf Ninject 3.0

Mein Problem ist: Bei der Portierung auf die neueste Version von Ninject und Ninject Interception Extension - 3.0 bekomme ich eine Ausnahme, wenn meine Interzeptoren ausgeführt werden sollen. Meine InterceptorRegistrationStrategy funktioniert einwandfrei, wenn der zugeordnete Typ aufgelöst und Interzeptoren registriert werden. Aber die abgehörten Methode ergibt folgende Ausnahme ausgeführt wird:

System.ArgumentException : Interface not found. 
at System.RuntimeTypeHandle.VerifyInterfaceIsImplemented(RuntimeTypeHandle handle, RuntimeTypeHandle interfaceHandle) 
at System.RuntimeType.GetInterfaceMap(Type ifaceType) 
at Ninject.Extensions.Interception.Advice.Advice.MatchesMethod(IProxyRequest request) 
at System.Linq.Enumerable.WhereListIterator`1.MoveNext() 
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection) 
at System.Linq.Enumerable.ToList(IEnumerable`1 source) 
at Ninject.Extensions.Interception.Registry.AdviceRegistry.GetInterceptorsForRequest(IProxyRequest request) 
at Ninject.Extensions.Interception.Registry.AdviceRegistry.GetInterceptors(IProxyRequest request) 
at Ninject.Extensions.Interception.Wrapper.StandardWrapper.CreateInvocation(IProxyRequest request) 
at Ninject.Extensions.Interception.Wrapper.DynamicProxyWrapper.Intercept(IInvocation castleInvocation) 
at Castle.DynamicProxy.AbstractInvocation.Proceed() 
at Infrastructure.Tests.Persistance.Conversations.NinjectConversationInterceptorBehavior.ShouldCreateInterceptorOnImplicitConversation() in NinjectConversationInterceptorBehavior.cs: line 74 

Ich bin irgendwie links nach Reflector greifen und mit Ninject Interception Erweiterung Quellen etwas über dieses Problem zu tun, gepaart mit nicht genug Dokumentation läßt es mich in einem schlechten Position.

Hat jemand die gleiche Ausnahme bei der Portierung auf Ninject 3.0?

Hier ist der Code, den ich die Abfangjäger registrieren verwenden, bezogen auf das Attribut automatisch:

public class NinjectConversationInterceptorRegistrationStrategy : InterceptorRegistrationStrategy 
{ 
    public NinjectConversationInterceptorRegistrationStrategy(IAdviceFactory adviceFactory, 
                   IAdviceRegistry adviceRegistry) 
     : base(adviceFactory, adviceRegistry) 
    { 
    } 

    public override void Execute(IPlan plan) 
    { 
     var pcAttribute = plan.Type.GetOneAttribute<PersistenceConversationalAttribute>(); 

     if (pcAttribute != null) 
     { 
      if (pcAttribute.MethodsIncludeMode == MethodsIncludeMode.Implicit) 
      { 
       foreach (var mi in GetCandidateMethods(plan.Type)) 
       { 
        RegisterMethodInterceptors(plan.Type, mi); 
        if (!plan.Has<ProxyDirective>()) 
        { 
         plan.Add(new ProxyDirective()); 
        } 
       } 
      } 
      else 
      { 
       foreach (
        var mi in 
         GetCandidateMethods(plan.Type).Where(
          mi => mi.HasAttribute<PersistenceConversationAttribute>())) 
       { 
        if (!mi.IsVirtual) 
        { 
         throw new InvalidOperationException(
          string.Format("[PersistentCoversation] attribute used on non-virtual method {0}.{1}", 
              mi.DeclaringType.Name, 
              mi.Name)); 
        } 
        RegisterMethodInterceptors(plan.Type, mi); 
        if (!plan.Has<ProxyDirective>()) 
        { 
         plan.Add(new ProxyDirective()); 
        } 
       } 
      } 
     } 
    } 

    protected virtual void RegisterMethodInterceptors(Type type, MethodInfo method) 
    { 
     IAdvice advice = this.AdviceFactory.Create(method); 
     advice.Callback = GetIntercepor; 
     this.AdviceRegistry.Register(advice); 
    } 

    protected virtual IInterceptor GetIntercepor(IProxyRequest arg) 
    { 
     var interceptor = new NinjectConversationLazyInterceptor(arg.Kernel); 
     return interceptor; 
    } 

    protected override bool ShouldIntercept(MethodInfo methodInfo) 
    { 
     if (IsPropertySetter(methodInfo)) 
     { 
      return false; 
     } 
     var ret = base.ShouldIntercept(methodInfo); 
     return ret; 
    } 

    private static bool IsPropertySetter(MethodBase methodInfo) 
    { 
     return methodInfo.IsSpecialName && methodInfo.Name.StartsWith("set_"); 
    } 
} 
+0

Ich benutze das auch: http : //stackoverflow.com/questions/5353476/ninject-one-interceptor-instance-per-one-class-instance-being-intercepted – Cortlendt

+0

Update - Ich bin den Typ aufzulösen, der Interzeptoren um es von der Schnittstelle hat, die es implementiert und Es sieht so aus, als ob die Auflösung der By-Schnittstelle für diese Ausnahme verantwortlich ist. Ich bin mir nicht ganz sicher, aber ich denke Codezeile - "InterfaceMapping interfaceMap = this.method.DeclaringType.GetInterfaceMap (request.Method.DeclaringType);" in Advice-Klasse ist die Quelle der Ausnahmen, um genauer zu sein - seine Parameter. – Cortlendt

+0

Fügen Sie einen Fehlerbericht zu github hinzu, der ein Projekt anfügt, das das Problem demonstriert. –

Antwort

3

Das Verhalten des Abfangens verändert: Die Erweiterung wird eine Schnittstelle erstellen Proxy, wenn eine Schnittstelle anstelle eines Klassenproxys injiziert wird, da dies den Vorteil hat, dass die Methoden nicht mehr virtuell sein müssen. Entweder müssen Sie es an die Schnittstelle setzen, die Methode von der Überwachung ausschließen (es ist nutzlos, eine Methode abzufangen, die sowieso nicht aufgerufen werden kann) oder eine Klasse anstelle einer Schnittstelle zu injizieren