5

Descriverò il mio ambiente: Ho l'estensione di intercettazione Ninject + Ninject che consente di abilitare la registrazione automatica degli intercettori per tutti i metodi, contrassegnati con un attributo speciale. È uno scenario comune di attributi AoP + + DI.Ninject Interception - interruzione delle modifiche durante il porting su Ninject 3.0

Il mio problema è: Durante il porting all'ultima versione di Ninject e Ninject Interception Extension - 3.0 inizio a ottenere un'eccezione quando si suppone che i miei intercettatori vengano eseguiti. My InterceptorRegistrationStrategy funziona correttamente quando si risolve il tipo attribuito e si registrano gli intercettori. Ma l'esecuzione dei risultati del metodo intercettati in seguente eccezione:

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 

Sono un po 'lasciato a ricorrere a riflettore e l'utilizzo di fonti Ninject Intercettazione Extension di fare qualcosa per questo problema, in coppia con la documentazione non è sufficiente che mi lascia in una cattiva posizione.

Chiunque ha la stessa eccezione durante il porting su Ninject 3.0?

Ecco il codice che uso per registrare le intercettori in base all'attributo automaticamente:

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

Sto anche usando questo: http : //stackoverflow.com/questions/5353476/ninject-one-interceptor-instance-per-one-class-instance-being-intercepted – Cortlendt

+0

Update - Sto risolvendo il tipo che ha intercettori attorno all'interfaccia che implementa e sembra che la risoluzione dell'interfaccia per colpa sia di questa eccezione. Non sono completamente sicuro, ma penso linea di codice - "InterfaceMapping interfaceMap = this.method.DeclaringType.GetInterfaceMap (request.Method.DeclaringType);" nella classe Advice è la fonte delle eccezioni, per essere più precisi - i suoi parametri. – Cortlendt

+0

Per favore aggiungi una segnalazione di bug su github allegando un progetto che mostri il problema. –

risposta

3

Il comportamento di intercettazioni cambiato: l'estensione creerà un'interfaccia proxy quando viene iniettata un'interfaccia anziché un proxy di classe perché questo ha il vantaggio che i metodi non devono più essere virtuali. O devi metterlo all'interfaccia, escludere il metodo dall'intercettazione (è inutile intercettare un metodo che non può essere chiamato comunque) o iniettare una classe invece di un'interfaccia