クラスに 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 の呼び出しが適切に変換されていないと考えています。これは、アスペクト拡張クラス内ではなく、アスペクト内にあるためです。アスペクトを持ちたいすべてのクラスでこれを呼び出すことを心配する必要がないように、これをきれいに自動化できる方法はありますか?