0

在一个项目中,我使用 Castle Dynamic Proxy 将所有由外观运行的代码包装在 try/catch 块中(听起来很奇怪?在此处解释)。这很好,但是为了确保所有方法调用都被拦截,当我遇到非虚拟的东西时,我会抛出一个异常,使用接口的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));
}

根据 Krzysztof Koźmic 的精彩教程对象类是特殊情况,默认情况下 DynamicProxy 将忽略它们。问题是,就我而言,它们没有被忽略,从以下示例MemberInfo数据中可以看出:

会员信息快速观看

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

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

4

2 回答 2

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);
        }
    }
于 2011-10-31T09:03:35.737 回答
2

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

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

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

不过,我可以看到这可能会令人困惑,因此我将看看 GetHasCode 作为一种特殊情况,即使在点击NonProxyableMemberNotification方法之前也可以轻松地进行预过滤。

于 2011-11-06T00:11:37.583 回答