Castle Dynamic Proxy想拦截Object.GetType()

时间:2011-07-12 15:50:55

标签: c# .net castle-dynamicproxy proxy-classes

在一个项目中,我使用Castle动态代理来包装所有由try / catch块中的façade运行的代码(听起来很奇怪?解释here)。这工作正常,但为了确保所有方法调用都被截获,当我遇到非虚拟的东西时,我使用NonProxyableMemberNotification接口的IProxyGenerationHook方法抛出异常:

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));
}

根据KrzysztofKoźmic的伟大tutorial; 对象类是特殊情况,默认情况下DynamicProxy将忽略它们。问题是,在我的情况下,它们不会被忽略,如以下示例MemberInfo数据所示:

memberInfo QuickWatch

我在这里错过了什么吗? NonProxyableMemberNotification是否应该触发Object方法?

我正在使用.Net 3.5,VS2010和Castle Core版本2.5.2,而我并没有覆盖Object.GetType()中的XmlDocumentBackend

2 个答案:

答案 0 :(得分: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);
        }
    }

答案 1 :(得分:2)

本教程是为DynamicProxy Version ... 2.1 IIRC编写的。

DynamicProxy的这个方面在最近的版本中发生了变化,因为有些情况下System.Object上的方法实际上需要被拦截。 (GerHashCodeEqualsToString ...)。因此,DP内部不会将System.Object列入黑名单,而是依赖于IProxyGenerationHookAllMethodsHook类)的默认实现来执行此操作(以便可以覆盖它)需要)。

因此,如果您希望预过滤System.Object方法,只需继承此类并使用base实现。

我可以看到这可能会让人感到困惑,所以我会看到GetHasCode是否可以在点击NonProxyableMemberNotification方法之前轻松预先过滤。