PostSharp 使用 DataContractSerializer 时?
我有一个在类上实现 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 的调用没有正确转换,因为它现在位于方面内部,而不是直接位于方面增强类内部。有没有一种方法可以完全自动化此操作,以便我不必担心在我想要拥有该方面的每个类上调用此操作?
I have an Aspect that implements INotifyPropertyChanged on a class. The aspect includes the following:
[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);
}
This works fine when I instantiate the class normally, but I run into problems when I deserialize the class using a DataContractSerializer. This bypasses the constructor, which I'm guessing interferes with the way that PostSharp sets itself up. This ends up causing a NullReferenceException in an intercepted property setter, but before it has called the custom OnPropertySet, so I'm guessing it interferes with setting up the LocationInterceptionArgs.
Has anyone else encountered this problem? Is there a way I can work around it?
I did some more research and discovered I can fix the issue by doing this:
[OnDeserializing]
private void OnDeserializing(StreamingContext context)
{
AspectUtilities.InitializeCurrentAspects();
}
I thought, okay, that's not too bad, so I tried to do this in my Aspect:
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();
}
Unfortunately, even though it intercepts the method properly, it doesn't work. I'm thinking the call to InitializeCurrentAspects isn't getting transformed properly, since it's now inside the Aspect rather than directly inside the aspect-enhanced class. Is there a way I can cleanly automate this so that I don't have to worry about calling this on every class that I want to have the Aspect?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
最近添加了对序列化的支持,并作为修补程序提供。
http://www.sharpcrafters.com/downloads/postsharp-2.0/hot-修复
Support for serialization has been added lately and is available as a hotfix.
http://www.sharpcrafters.com/downloads/postsharp-2.0/hot-fixes