PostSharp when using DataContractSerializer?

Posted by Dan Bryant on Stack Overflow See other posts from Stack Overflow or by Dan Bryant
Published on 2010-04-17T17:23:50Z Indexed on 2010/04/17 19:53 UTC
Read the original article Hit count: 395

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?

© Stack Overflow or respective owner

Related posts about postsharp

Related posts about datacontractserializer