PostSharp при использовании DataContractSerializer? - PullRequest
0 голосов
/ 17 апреля 2010

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

1 Ответ

2 голосов
/ 18 апреля 2010

Поддержка сериализации была добавлена ​​в последнее время и доступна в качестве исправления.

http://www.sharpcrafters.com/downloads/postsharp-2.0/hot-fixes

...