城DynamicProxy v1のパラメータを持つ例外ときにプロキシ-INGの方法?
-
25-09-2019 - |
質問
私は城DynamicProxyのv1.1.5.0を使用してパラメータをmetodsをプロキシの問題を抱えています。 - 私は例外を取得、「インデックスが配列の境界外だったの。」
私は、パラメータなし、OR DynamicProxy v2の持つメソッドを使用している場合は、は、すべてがOKに動作します。
残念ながら、私はV2に依存関係を追加するために私のプロジェクトのリードを納得させる問題が発生した(それはNHibernateは付属していて、我々はすでに、V1を使用している)しています。
私の質問は、つまるところだから:これはV1で行うことができますか?アム私が間違っそれを使用していますか?
ここで核心ザラザラだ。
私は、基本クラスにコンパイル時の依存関係を持つことなく継承をシミュレートするメカニズムを実装しました。 Pleeease理由を聞かないで、理由は醜いです:(
ここでどのようにこの休憩を示す完全な例です。私はCastle.DynamicProxy.dll(V1)を参照しています。私はCastle.DynamicProxy [B] 2への参照を変更する場合、[/ B]の.dll(+ Castle.Core.dll)、非コメントコードの開始時の#define
申し訳ありませんが、長いっぽいコードのため、私は、私はいくつかの重要なディテールを出すかもしれない恐れていた...
また:免責事項:コードサンプルは、いくつかの厄介なバグを持っています! (おそらくより私も、見られるよりも:)
//#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 { }
}
やれやれ!それは一口です。 ここで、V1を使用するときに発生する例外があります:
{"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[])}
V2で実行している場合は、すべて私の取得が正しい出力されます:
派生- フー! 派生 - !バズ
...ヘルプ?
解決
古いDynamicProxyを使用しないでください。それは長いサポートされていません。あなたはそれが付属してNHibernateはを使用している場合は、私もあなたが使用しているNHibernateはどのバージョンの依頼する必要はありません。 DPV1はの本当にの古い