2011-07-12 74 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