5

Describiré mi entorno: Tengo Ninject + Ninject Interception Extension trabajando para habilitar el registro automático de interceptores para todos los métodos, marcados con un atributo especial. Es un escenario común de atributos AoP + atributos + contenedor.Intervención de Ninject - rompiendo cambios al portar a Ninject 3.0

Mi problema es: Al migrar a la última versión de Ninject y Ninject Interception Extension - 3.0, empiezo a obtener una excepción cuando se supone que se deben ejecutar mis interceptores. My InterceptorRegistrationStrategy funciona bien al resolver el tipo atribuido y registrar interceptores. Pero el funcionamiento de los resultados del método interceptados en siguiente excepción:

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 

Soy un poco dejó de recurrir a reflector y el uso de fuentes de Ninject Interceptación de extensión que hacer algo con este problema, junto con la documentación no es suficiente que me deja en un mal posición.

¿Alguien tiene la misma excepción al portar a Ninject 3.0?

Aquí está el código que utilizo para registrar los interceptores con base en el atributo de forma automática:

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

También estoy usando esto: http : //stackoverflow.com/questions/5353476/ninject-one-interceptor-instance-per-one-clase-instance-being-intercepted – Cortlendt

+0

Actualización: estoy resolviendo el tipo que tiene interceptores a su alrededor por la interfaz que implementa y parece que resolver la interfaz por es la culpa de esta excepción. No estoy del todo seguro, pero creo que es una línea de código: "InterfaceMapping interfaceMap = this.method.DeclaringType.GetInterfaceMap (request.Method.DeclaringType);" en la clase de asesoramiento es la fuente de las excepciones, para ser más precisos, sus parámetros. – Cortlendt

+0

Agregue un informe de error en github adjuntando un proyecto que demuestra el problema. –

Respuesta

3

El comportamiento de intercepción cambió: la extensión creará una interfaz proxy cuando se inyecta una interfaz en lugar de un proxy de clase porque tiene la ventaja de que los métodos ya no necesitan ser virtuales. O tiene que ponerlo en la interfaz, excluir el método de la interceptación (es inútil interceptar un método que no se puede llamar de todos modos) o inyectar una clase en lugar de una interfaz