2010-02-02 2 views
0

Castle DynamicProxy v1.1.5.0을 사용하여 매개 변수로 metods를 프록 싱하는 데 문제가 있습니다. - "인덱스가 배열 범위를 벗어났습니다."라는 예외가 발생합니다.성 매개 변수가있는 메소드를 프록시 할 때 성 DynamicProxy v1 예외?

매개 변수가없는 메소드 또는 DynamicProxy v2 만 사용하는 경우 모두 정상입니다.
불행히도, 프로젝트에서 리드를 확신 시켜서 v2에 의존성을 추가하는 데 어려움을 겪고 있습니다. 우리는 이미 NHibernate와 함께 제공되는 v1을 사용하고 있습니다.

제 질문은 다음과 같습니다. v1에서 할 수 있습니까? 나는 그것을 잘못 사용하고 있는가?

다음은 핵심 사항입니다.

저는 기본 클래스에 컴파일 타임 종속성을 갖지 않고 상속을 시뮬레이트하는 메커니즘을 구현했습니다. 이유가 추악한 이유를 묻지 마세요 : (

여기는 어떻게 깨는 지 보여주는 완벽한 예입니다. Castle.DynamicProxy.dll (v1)을 참조하고 있습니다. Castle.DynamicProxy [ b] 2 [/ b] .dll (+ Castle.Core.dll), 코드 시작 부분에 #define을 주석으로 처리 해제하십시오.

죄송하지만 long-ish 코드는 유감스럽게 생각합니다. 몇 가지 중요한 세부에서 ...
또한 : 면책 조항 : 코드 샘플은 성가신 버그가 (아마 내가 찾은보다 더 많은, 너무 :

//#define DynamicProxyV2 

using System; 
using System.Collections.Generic; 
using System.Diagnostics; 
using System.Reflection; 


#if DynamicProxyV2 
using Castle.Core.Interceptor; 
#endif 

using Castle.DynamicProxy; 

namespace ProxyTest 
{ 

    public interface IMyInterface 
    { 
     void Foo(object a); 
     void Bar(object a); 
     void Baz(object a); 
    } 
    public interface IParam 
    { 
     string Value { get;} 
    } 

    public class DefaultImplementation : IMyInterface{ 
     public virtual void Foo(object a) { 
      Console.WriteLine("Default Foo"); 
      Bar(null); 
     } 

     public virtual void Bar(object a){ 
      Baz(null); 
     } 

     public virtual void Baz(object a){ 
      Console.WriteLine("Default Baz"); 
     } 
    } 

    class DerivedImpl : ProxyDerivedImplementation { 
     public DerivedImpl(IMyInterface i_baseImpl) 
      : base(i_baseImpl) { } 

     public override void Foo(object a) { 
      Console.WriteLine("Derived - Foo!"); 
      base.Bar(null); 
     } 

     public override void Baz(object a) { 
      Console.WriteLine("Derived - Baz!"); 
     } 
    } 

    public class DoStuff { 
     [STAThread] 
     public static void Main() 
     { 
      Type t = typeof(DefaultImplementation); 

      IMyInterface defaultImpl = (IMyInterface)Activator.CreateInstance(t); 
      DerivedImpl derived = new DerivedImpl(defaultImpl); 
      derived.Foo(null); 
     } 
    } 


    public class ProxyDerivedImplementation : IMyInterface, IInterceptor { 
     private IMyInterface m_proxy; 
     public ProxyDerivedImplementation(IMyInterface i_defaultImplementation) 
     { 
      ProxyGenerator pg = new ProxyGenerator(); 

      Type tt = i_defaultImplementation.GetType(); 
      m_proxy = (IMyInterface)pg.CreateClassProxy(tt, this); 
     } 

#if DynamicProxyV2 
     #region DynProxy v2 
     public void Intercept(IInvocation invocation) { 
      try 
      { 
       MethodInfo i_method = invocation.Method; 
       List<Type> types = new List<Type>(); 

       foreach (ParameterInfo info in i_method.GetParameters()) 
       { 
        types.Add(info.ParameterType); 
       } 
       MethodInfo method = this.GetType().GetMethod(i_method.Name, types.ToArray()); 
       object[] attrs = method.GetCustomAttributes(typeof(NotOverridenAttribute), false); 
       if (attrs.Length > 0) 
       { 
        invocation.Proceed(); 
       } 
       else 
       { 
        invocation.ReturnValue = method.Invoke(this, invocation.Arguments); 
       } 
      } 
      catch (Exception ex) 
      { 
       Debug.Fail(ex.Message); 
       //return null; 
      } 

     } 
     #endregion 
#else 
     #region DynProxy v1 
     public object Intercept(IInvocation i_invocation, params object[] args) { 
      try { 
       MethodInfo proxiedMethod = i_invocation.Method; 
       List<Type> types = new List<Type>(); 

       foreach (ParameterInfo info in proxiedMethod.GetParameters()) 
       { 
        types.Add(info.ParameterType); 
       } 

       //find the corresponding method in the inheritance tree having this class as root 
       MethodInfo localMethod = this.GetType().GetMethod(proxiedMethod.Name, types.ToArray()); 
       object[] attrs = localMethod.GetCustomAttributes(typeof(NotOverridenAttribute), false); 
       if (attrs.Length > 0) 
       { 
        //it's one of the methods in THIS class, i.e. it's not overridden 
        //-> we can't call the method in this class, because it will re-trigger this intercept 
        // and we'd get an infinite loop 
        // => just dispatch the method to the original proxied type 
        // 
        return i_invocation.Proceed(); 
       } 
       //else we have an override for this method - call it. 
       return localMethod.Invoke(this, args); 
      } catch (Exception ex) { 
       Debug.Fail(ex.Message); 
       return null; 
      } 
     } 
     #endregion 
#endif 
     [NotOverriden] 
     public virtual void Foo(object a) { m_proxy.Foo(a); } 

     [NotOverriden] 
     public virtual void Bar(object a) { m_proxy.Bar(a); } 

     [NotOverriden] 
     public virtual void Baz(object a) { m_proxy.Baz(a); } 
    } 

    class NotOverridenAttribute : Attribute { } 

} 

이 휴 그건 입입니다!. 푸 -

유래 : v2와 함께 실행하는 경우

{"Index was outside the bounds of the array."} 
    [System.IndexOutOfRangeException]: {"Index was outside the bounds of the array."} 
    Data: {System.Collections.ListDictionaryInternal} 
    HelpLink: null 
    InnerException: null 
    Message: "Index was outside the bounds of the array." 
    Source: "DynamicAssemblyProxyGen" 
    StackTrace: " at CProxyTypeDefaultImplementationProxyTest0.__delegate_2.Call(Object[])\r\n at Castle.DynamicProxy.Invocation.AbstractInvocation.Proceed(Object[] args)\r\n at ProxyTest.ProxyDerivedImplementation.Intercept(IInvocation i_invocation, Object[] args) in D:\\My Documents\\Visual Studio 2005\\Projects\\DefaultImpl\\AddedValue\\AddedValue.cs:line 133" 
    TargetSite: {System.Object Call(System.Object[])} 

, 내가 얻을 모두가 올바른 출력은 다음과 같습니다 여기 V1을 사용하는 경우 발생하는 예외입니다! 파생 된 - Baz!

... 도움말?

답변

1

이전 DynamicProxy를 사용하지 마십시오. 오랫동안 지원되지 않았습니다. NHibernate와 함께 제공되는 NHibernate를 사용하고 있다면, 사용중인 NHibernate의 버전을 묻고 싶지 않습니다. DPv1은 입니다. 정말입니다.

+0

업 그레 이드 : 나는 업 그레 이드에게 업 그레 이드를 설득하고 있습니다. :) –