在一个项目中,我使用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
数据所示:
我在这里错过了什么吗? NonProxyableMemberNotification
是否应该触发Object方法?
我正在使用.Net 3.5,VS2010和Castle Core版本2.5.2,而我并没有覆盖Object.GetType()
中的XmlDocumentBackend
。
答案 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上的方法实际上需要被拦截。 (GerHashCode
,Equals
,ToString
...)。因此,DP内部不会将System.Object
列入黑名单,而是依赖于IProxyGenerationHook
(AllMethodsHook
类)的默认实现来执行此操作(以便可以覆盖它)需要)。
因此,如果您希望预过滤System.Object
方法,只需继承此类并使用base
实现。
我可以看到这可能会让人感到困惑,所以我会看到GetHasCode是否可以在点击NonProxyableMemberNotification
方法之前轻松预先过滤。