5

自分の環境について説明します。Ninject + Ninject Interception Extensionを使用して、特別な属性が設定されたすべてのメソッドに対してインターセプタの自動登録を有効にします。一般的なAoP +属性+ DIコンテナのシナリオです。Ninjectの傍受 - Ninject 3.0に移植する際の変更点

私の問題は、次のとおりです。 NinjectとNinject傍受拡張の最新版に移植する場合 - 3.0私は私のインターセプタを実行することになっているときに例外を取得するために開始します。 My InterceptorRegistrationStrategyは、属性タイプを解決してインターセプタを登録するときに問題なく動作します。しかし、例外を以下にインターセプトさメソッドの結果を実行している:それは悪いで私の葉は十分ではないのドキュメントとペアになって、

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 

私はちょっとリフレクターに頼る左だし、この問題について何かをするためにNinject傍受拡張ソースを使用してポジション。

誰かがNinject 3.0に移植するときに同じ例外がありますか?ここで

は、私は自動的に属性に基づいてインターセプタを登録するために使用するコードです:

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

私もこれを使っている:http ://stackoverflow.com/questions/5353476/ninject-one-interceptor-instance-per-one-class-instance-being-intercepted – Cortlendt

+0

更新 - 私はそれが実装しているインターフェイスによって周囲のインターセプタを持つ型を解決しています。 byインタフェースを解決するように見えるのは、この例外に対して責任があることです。私は完全にはわかりませんが、私はコードのライン - "InterfaceMapping interfaceMap = this.method.DeclaringType.GetInterfaceMap(request.Method.DeclaringType);" Adviceクラスでは例外のソース、より正確にはそのパラメータ、そのパラメータです。 – Cortlendt

+0

問題を示すプロジェクトを添付しているgithubに関するバグレポートを追加してください。 –

答えて

3

動作が変更されました:拡張インターフェイスを作成します。これは、メソッドがもはや仮想である必要がないという利点があるため、クラスプロキシではなくインターフェイスが注入されたときにプロキシとして扱われます。あなたはそれをインターフェースに置かなければならないか、メソッドをインターセプトから除外しなければならないか(それはとにかく呼び出せないメソッドをインターセプトするのには役に立たない)、あるいはインターフェースの代わりにクラスをインジェクトする。

1

問題は、プロジェクトのGitのハブに移動:傍受のissue