例如:
class BaseClass : IDisposable {
[LogMethod]
public BaseClass() {
}
[LogMethod] // This is OnMethodBoundaryAspect with MulticastInheritance.Strict
public virtual void Dispose() { // overridden method
}
}
class SubClass : BaseClass {
public SubClass() : base() { // this doesn't lead to double LogMethod invoking
}
public override void Dispose() { // overriding method
base.Func(); // this leads to double LogMethod invoking
}
}
问题是base.Func()
导致双向调用。有可能防止这种情况吗?
答案 0 :(得分:1)
不更改代码或更改方面本身是不可能的。
原因是PostSharp转换方法代码。它将对方面的调用添加到BaseClass.Dispose的方法主体和SubClass.Dispose
的方法主体中。由于BaseClass.Dispose
会调用SubClass.Dispose
,因此这两个方面都会得到执行。
要在从BaseClass.Dispose
调用SubClass.Dispose
时禁用方面,您需要将有关其调用者的信息传递给base方法。在不更改代码的情况下(这会破坏方面的目的),可以通过更改方面使用AsyncLocal
或[ThreadStatic]
在方面实例之间传递状态。
答案 1 :(得分:0)
这可能是最好的方法。我只是忽略登录重写的方法。
void IInstanceScopedAspect.RuntimeInitializeInstance() {
IsEnabled = !IsOverridden( method, instance );
}
private static bool IsOverridden(MethodBase method, object instance) {
if (method is MethodInfo method_) return instance.GetType().HasOverridingMethod( method_ );
return false;
}
public static bool HasOverridingMethod(this Type type, MethodInfo baseMethod) {
return type.GetOverridingMethod( baseMethod ) != null;
}
public static MethodInfo GetOverridingMethod(this Type type, MethodInfo baseMethod) {
var flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod;
return type.GetMethods( flags ).FirstOrDefault( i => baseMethod.IsBaseMethodOf( i ) );
}
private static bool IsBaseMethodOf(this MethodInfo baseMethod, MethodInfo method) {
return baseMethod.DeclaringType != method.DeclaringType && baseMethod == method.GetBaseDefinition();
}