5

Tôi sẽ mô tả môi trường của mình: Tôi có Tiện ích mở rộng đánh chặn Ninject + Ninject để kích hoạt đăng ký tự động các bộ chặn cho tất cả các phương pháp, được đánh dấu bằng thuộc tính đặc biệt. Đó là một thuộc tính AoP + chung + Kịch bản vùng chứa DI.Ninject Interception - thay đổi đột ngột khi chuyển sang Ninject 3.0

Vấn đề của tôi là: Khi chuyển sang phiên bản mới nhất của Tiện ích đánh chặn Ninject và Ninject - 3.0 Tôi bắt đầu có ngoại lệ khi máy đánh chặn của tôi được cho là chạy. My InterceptorRegistrationStrategy hoạt động tốt khi phân giải loại được phân bổ và đăng ký đánh chặn. Nhưng chạy kết quả phương pháp chặn trong ngoại lệ sau đây:

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 

tôi là kinda trái phải nghỉ mát để Reflector và sử dụng các nguồn Ninject chặn mở rộng để làm điều gì đó về vấn đề này, kết hợp với không đủ tài liệu hướng dẫn nó để lại tôi trong một xấu Chức vụ.

Bất kỳ ai cũng có cùng ngoại lệ khi chuyển sang Ninject 3.0?

Dưới đây là đoạn code tôi sử dụng để đăng ký chặn dựa trên thuộc tính tự động:

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

Tôi cũng đang sử dụng: http : //stackoverflow.com/questions/5353476/ninject-one-interceptor-instance-per-one-class-instance-being-intercepted – Cortlendt

+0

Cập nhật - tôi đang giải quyết loại có bộ chặn xung quanh nó bằng giao diện mà nó thực hiện và có vẻ như giải quyết giao diện bằng cách đổ lỗi cho ngoại lệ này. Tôi không hoàn toàn chắc chắn, nhưng tôi nghĩ dòng mã - "InterfaceMapping interfaceMap = this.method.DeclaringType.GetInterfaceMap (request.Method.DeclaringType);" trong lớp Tư vấn là nguồn ngoại lệ, chính xác hơn - các tham số của nó. – Cortlendt

+0

Vui lòng thêm báo cáo lỗi về github đính kèm dự án trình bày sự cố. –

Trả lời

3

Hành vi của đánh chặn thay đổi: phần mở rộng sẽ tạo ra một giao diện proxy khi giao diện được tiêm thay vì proxy lớp bởi vì điều này có lợi thế là các phương thức không cần phải ảo nữa. Hoặc bạn phải đặt nó vào giao diện, loại trừ phương thức khỏi bị chặn (vô ích khi chặn một phương thức không thể gọi được) hoặc tiêm một lớp thay vì giao diện