У меня есть аспект, который реализует 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();
}
К сожалению, даже если он правильно перехватывает метод, он не работает.Я думаю, что вызов InitializeCurrentAspect не трансформируется должным образом, поскольку теперь он находится внутри Aspect, а не непосредственно внутри класса с расширенными аспектами.Есть ли способ, которым я могу полностью автоматизировать это, чтобы мне не пришлось беспокоиться о вызове этого в каждом классе, в котором я хочу использовать Аспект?