我有这种类型:
[NotifyPropertyChangedAspect]
public class MyDataModel
{
...
[OnSetAspect("OnSelectedUserChanged")]
public string SelectedUser { get; set; }
...
}
我应用这些方面:每班级方面:
[Serializable]
public class NotifyPropertyChangedAspect : LocationInterceptionAspect
{
...
public override void OnSetValue(LocationInterceptionArgs args)
{
var newValue = args.Value;
var oldValue = args.GetCurrentValue();
args.ProceedSetValue();
//base.OnSetValue(args); // same effect of ProceedSetValue()
... /* some more stuff... */ ...
}
...
}
和每个字段方面:
[Serializable]
public class OnSetAspect : LocationInterceptionAspect
{
...
public override void OnSetValue(LocationInterceptionArgs args)
{
var newValue = args.Value;
var oldValue = args.GetCurrentValue();
args.ProceedSetValue();
//base.OnSetValue(args); // same effect of ProceedSetValue()
... /* some more stuff... */ ...
}
...
}
现在发生的事情是NotifyPropertyChangedAspect.OnSetValue(...)
被调用,当它调用args.GetCurrentValue()
时,args.Value
会更改其值(由于aspect绑定中的下一个节点,我猜)所以当调用OnSetAspect.OnSetValue(...)
时,args.Value
不再有效。
这两个方面都应该检查以前的值和新值(意味着即将设置的值)并做相应的事情。
它们不会改变要设置的值,所以它们不应该相互影响,但是它们会...
如何解开这两个方面?
答案 0 :(得分:0)
这里的误解是,当您在类上指定aspect属性时,它不会应用于该类,而是在该类上进行多播。多播是一种机制,它将属性(不是方面!)递归地应用于所有包含的声明,甚至是派生的声明。请参阅PostSharp documentation on this matter。
真正应用方面的声明是与方面级别匹配的声明。有以下基本方面级别:
Aspect的运行时实例然后每个实体存在一次。即在您的情况下,每个位置都有一个单例方面实例。
在你的情况下,你将一个LocationLevelAspect应用于一个类,这使得方面在所有字段上被多播,因此你最终在每个字段/属性上都有两个LocationInterceptionAspects。
args.GetCurrentValue()
获取基础属性的值,但不应更改args.Value
,它与属性设置器中的value
参数具有相同的语义。
因此,方面并没有真正纠结,它们按顺序应用(您可以指定)。并且始终完全包装前一个。