2012-06-18 21 views
6

我正在使用Castle DynamicProxy向我的类型添加拦截器。 现在我需要获取底层基础类型(不是代理本身)。Castle DynamicProxy:获取未加密的对象

我发现这么几个暗示,建议使用ProxyUtil类是这样的:

object realInstance = ProxyUtil.GetUnproxiedInstance(proxyInstance); 

这似乎并不工作,因为

bool isProxy = ProxyUtil.IsProxy(realInstance); 

总是正确的。

我也使用下面的代码段,这基本上是什么ProxyUtil正在做尝试:

var accessor = proxyInstance as IProxyTargetAccessor; 
var realInstance = accessor.DynProxyGetTarget(); 

具有相同的结果,realInstance仍然是一个代理。

我在这里错过了什么?

回答

1

我只是用这样的

public interface IMarker 
{ 
    Type ActualType { get; } 
} 

的接口将它添加到我的代理和拦截它:

public class MyInterceptor<T> : IInterceptor 

...

if (invocation.Method.DeclaringType == typeof(IMarker)) 
{ 
    if (invocation.Method.Name.Equals("get_ActualType")) 
    { 
    invocation.ReturnValue = typeof(T); 
    return; 
    } 
} 

所以最后只有我必须检查

if(obj is IMarker) 
    Type t = (obj as IMarker).ActualType` 

也许有更好的选择来做到这一点,但它有效,并保持我的代码清除城堡引用。 希望这有助于。

1

如果您正在构建基于继承的代理(generator.CreateClassProxy<MyClass>()),代理的目标。

+2

我使用'CreateClassProxyWithTarget (实例,拦截器)'来创建代理。 问题是NHibernate失败,因为它认为它应该映射代理,而不是目标。 – cguedel

8

这个问题有点老,但希望我的解决方案(它依赖于.NET 4+)将帮助某人。

已经创建的代理如下:

ProxyGenerator generator = new ProxyGenerator(); 
MyClass proxy = generator.CreateClassProxyWithTarget(underlying, new MyInterceptor(this)); 

我已经能够得到基本目标有以下方法:

internal static TType UnwrapProxy<TType>(TType proxy) 
{ 
    if (!ProxyUtil.IsProxy(proxy)) 
     return proxy; 

    try 
    { 
     dynamic dynamicProxy = proxy; 
     return dynamicProxy.__target; 
    } 
    catch (RuntimeBinderException) 
    { 
     return proxy; 
    } 
} 

它依赖于内部实现城堡 - 即生成的代理有一个__target成员。这是很好的和自我包含,然后用单元测试或两个备份,我们应该抓住任何变化,如果城堡的更高版本打破这一点。这是使用Castle的v3.2.0.0。

+0

这为我工作:),谢谢 – dbones

+0

'动态'在这里赢了。试图反思它的节拍。这是史诗般的失败。 – IAbstract

相关问题