views:

431

answers:

2

Hi

I'm using PostSharp to apply a CompoundAspect to a ActiveRecord class (from CastleProject). The code looks like this:

public override void ProvideAspects(object targetElement, LaosReflectionAspectCollection collection)
{
    Type targetType = (Type)targetElement;
    RevertibleSubAspect revertible = new RevertibleSubAspect();
    revertible.Cascade = this.Cascade;
    collection.AddAspect(targetType, revertible);

    //This isn't working
    MethodInfo saveMethod = targetType.GetMethod("Save");
    collection.AddAspect(saveMethod, new CommitOnSaveSubAspect());

    foreach (PropertyInfo property in targetType.GetProperties())
    {
        if((this.Only != null && this.Only.IndexOf(property.Name) == -1) ||
           (this.Except != null && this.Except.IndexOf(property.Name) > -1))
        {
            continue;
        }

        if (property.DeclaringType == targetType && property.CanWrite)
        {
            MethodInfo method = property.GetSetMethod();
            if (method != null && !method.IsStatic)
            {
                collection.AddAspect(method, new TrackInitialPropertyValuesSubAspect());
            }
        }
    }
}

Everything works fine, except the CommitOnSaveSubAspect which is a OnMethodBoundaryAspect. The OnSuccess method never gets called when the Save method is invoked. I have already tried moving the code to OnEntry and OnExit but same situation here.

The CommitOnSaveSubAspect class looks like this:

[Serializable]
class CommitOnSaveSubAspect : OnMethodBoundaryAspect
{
    public override void OnSuccess(MethodExecutionEventArgs eventArgs)
    {
        ((IRevertible)eventArgs.Instance).Commit();
    }
}

Am I applying the aspect the wrong way?

A: 

Was PostSharp defined globally when you installed it? Otherwise, you'll have to edit your project files in order for PostSharp to be injected properly into your assemblies.

See http://doc.postsharp.org/1.0/Default.aspx##PostSharp.HxS/UserGuide/Platform/EnablingPostSharp.html.

David Andres
PostSharp was defined globally when I installed it. If it wouldn't have been defined globally, none of the code above would work. But it's only the CommitOnSaveSubAspect that doesn't work.
Mato
+1  A: 

A good way to debug an aspect is to look at the resulting assembly using Reflector. Are methods enhanced as you expect?

You can also debug the ProvideAspects method by putting a breakpoint into it and running msbuild with the following command line:

msbuild /p:PostSharpAttachDebugger=true
Gael Fraiteur
OK, it looks like the method isn't enhanced as expected (it doesn't get changed at all). But the debugger shows that getMethod("Save") finds the method and returns the correct MethodInfo. Could the problem be that the method is virtual? When I overide the mthod in the class I'm applying the attribute to the method gets enhanced as expected.
Mato
When you add an aspect to a virtual method, the aspect is applied to the precise method you annotated with the aspect. See http://doc.postsharp.org/1.5/##PostSharp.HxS/UserGuide/Laos/Multicasting/Inheritance.html for details about aspects that apply also to overrides.
Gael Fraiteur