Search code examples
c#interfaceaoppostsharp

Postsharp OnMethodBoundryAspect on interface implementation


I have code that roughly looks like this

IInterface {

   public MyClass GetSomething();
}

public MyService : IInterface {

   [NeverNull]
   public GetSomething() {
       if (canAccess) {
          return new MyClass();
       }
       return null;
   }
}

[Serializable]
public NeverNullAttribute : OnMethodBoundryAspect {
     OnSuccess(MethodExecutionArgs args ) {
         if (args.ReturnValue == null){
             args.ReturnValue = new MyClass();
         }
     }
}

Now my attribute seems to be used if i call code like this

public void SomeMethod() {
     var myService = new MyService();
     Assert.IsNotNull(myService.GetSomething()); //this always works


     var interface = //use unity to get a instance instance of MyService
     Assert.IsNotNull(interface.GetSomething()); //this can fail since GetSomething is properly executed, but the NeverNull aspect doesn't seem to be executed.
}

My real code is a bit more involved but i hope this demonstrates the problem, namely that the OnSuccess doesn't get executed if i use the interface way of calling the method.

I use postsharp express. It would be an option to upgrade if i was certain it would solve this problem.

Update: I made the methods virtual as suggested, this seems to have no effect. ON other places where i directly create a instance of a class with attributes it does work so i know something of postsharp is working.

Update: Could it be that the aspects (which are defined in another project) are not weaved in my code properly?


Solution

  • The problem was that PostSharp was included but for some reason it wasn't enabled on the project containing MyService. for anyone else having issues, due to IL-Weaving (the awsomeness of postsharp) the aspect OnEntry/OnSuccess will be INSIDE the method if you look at your method using IL SPY. the method should for example look like this

    public SomeObject GetSomething(){
        MethodExecutionArgs methodExecutionArgs = new MethodExecutionArgs(null, null);
    
        /* original method code here */ 
    
        methodExecutionArgs.ReturnValue = returnValue;
        <>z__a_1.a0.OnSuccess(methodExecutionArgs);
        return (SomeObject)methodExecutionArgs.ReturnValue;
    }
    

    However i noticed that the postsharp code wasn't there on this specific method (in this project) and it was on other places where i was using my postsharp aspect.

    For some reason even the enable postsharp button on my project properties wasn't working either so i had to manual edit my csproj file.

    It would be nice if there was some way to detect at compile time that postsharp wasn't loaded properly.