我有一个在类上实现 INotifyPropertyChanged 的方面。该方面包括以下内容:
[OnLocationSetValueAdvice, MethodPointcut("SelectProperties")]
public void OnPropertySet(LocationInterceptionArgs args)
{
var currentValue = args.GetCurrentValue();
bool alreadyEqual = (currentValue == args.Value);
// Call the setter
args.ProceedSetValue();
// Invoke method OnPropertyChanged (ours, the base one, or the overridden one).
if (!alreadyEqual)
OnPropertyChangedMethod.Invoke(args.Location.Name);
}
当我正常实例化类时,这工作正常,但是当我使用 DataContractSerializer 反序列化类时遇到问题。这绕过了构造函数,我猜这会干扰 PostSharp 设置自己的方式。这最终导致在拦截的属性设置器中出现 NullReferenceException,但在它调用自定义 OnPropertySet 之前,所以我猜它会干扰设置 LocationInterceptionArgs。
有没有其他人遇到过这个问题?有没有办法解决它?
我做了一些更多的研究,发现我可以通过这样做来解决这个问题:
[OnDeserializing]
private void OnDeserializing(StreamingContext context)
{
AspectUtilities.InitializeCurrentAspects();
}
我想,好吧,这还不错,所以我尝试在我的方面做到这一点:
private IEnumerable<MethodInfo> SelectDeserializing(Type type)
{
return
type.GetMethods(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public).Where(
t => t.IsDefined(typeof (OnDeserializingAttribute), false));
}
[OnMethodEntryAdvice, MethodPointcut("SelectDeserializing")]
public void OnMethodEntry(MethodExecutionArgs args)
{
AspectUtilities.InitializeCurrentAspects();
}
不幸的是,即使它正确地拦截了该方法,它也不起作用。我认为对 InitializeCurrentAspects 的调用没有正确转换,因为它现在位于 Aspect 内部,而不是直接位于方面增强类内部。有没有一种方法可以让我完全自动化,这样我就不必担心在我想要拥有 Aspect 的每个类上调用它?