2012-06-18 25 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

相關問題