2011-07-12 122 views
0

在一個項目中,我使用Castle動態代理將try/catch塊中的所有由façade運行的代碼包裝起來(聽起來很奇怪嗎?解釋here)。這工作正常,但要確保所有的方法調用被攔截,我拋出一個異常,當我遇到一些非虛,使用IProxyGenerationHook接口的NonProxyableMemberNotification方法:城堡動態代理想攔截Object.GetType()

public void NonProxyableMemberNotification(Type type, MemberInfo memberInfo) 
{ 
    throw new InvalidOperationException(string.Format(
      "Proxy failure. {0} {1} in {2} is not virtual.", 
      memberInfo.MemberType, memberInfo.Name, memberInfo.DeclaringType)); 
} 

據剋日什托夫·Koźmic的偉大tutorial; 對象類是特殊情況,DynamicProxy默認會忽略它們。問題是,在我的情況下,他們不會被忽略,從下面的示例MemberInfo數據看出:

memberInfo QuickWatch

有什麼我已經在這裏錯過了嗎?是NonProxyableMemberNotification應該在Object方法上觸發?

我使用的是.Net 3.5,VS2010和Castle Core 2.5.2版本,並且我不是在覆蓋Object.GetType()我的XmlDocumentBackend

回答

2

使用此實現NonProxyableMemberNotification的:

public void NonProxyableMemberNotification(Type type, System.Reflection.MemberInfo memberInfo) 
    { 
     if (memberInfo.DeclaringType != typeof(object)) 
     { 
      string message = string.Format("Non-proxyable member encountered - {0} (type - {1})", 
       memberInfo.Name, type.FullName); 
      throw new InvalidOperationException(message); 
     } 
    } 
2

本教程是爲DynamicProxy版本編寫... 2.1 IIRC。

DynamicProxy的這方面已經在更新的版本中發生了變化,因爲有些情況下System.Object上的方法實際上需要被攔截。 (GerHashCode,Equals,ToString ...)。由於這個原因,DP內部不會將System.Object從可攔截的黑名單中刪除,而是依靠IProxyGenerationHookAllMethodsHook類)的默認實現來執行此操作(以便可以在需要時覆蓋它)。

所以如果你想要System.Object方法進行預過濾只是從這個類繼承和使用base實現。

雖然我可以看到這可能會令人困惑,但是我會看到GetHasCode作爲一種特殊情況,即使在觸碰NonProxyableMemberNotification方法之前也可以輕鬆預過濾。

+0

感謝您的答案,這真的解釋了很多! – joneberg