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!
... 도움말?
업 그레 이드 : 나는 업 그레 이드에게 업 그레 이드를 설득하고 있습니다. :) –