Postsharp OnMethodBoundryAspect on interface implementation

时间:2014-08-20 11:26:02

标签: c# interface aop postsharp

我的代码大致看起来像这样

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();
         }
     }
}

现在我的属性似乎被用来调用这样的代码

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.
}

我的真实代码涉及更多,但我希望这能说明问题,即如果我使用调用方法的接口方式,OnSuccess就不会被执行。

我使用postharp express。如果我确定它可以解决这个问题,那么升级是一个选择。

更新:我按照建议将方法设为虚拟,这似乎没有效果。在其他地方,我直接创建一个具有属性的类的实例,它确实有效,所以我知道postharp正在工作。

更新:可能是因为我的代码中没有正确编织方面(在另一个项目中定义)吗?

1 个答案:

答案 0 :(得分:3)

问题在于包含了PostSharp,但由于某种原因,它未在包含MyService的项目上启用。 对于其他任何有问题的人,由于IL-Weaving(postharp的精彩),如果你使用IL SPY查看你的方法,OnEntry / OnSuccess方面将是INSIDE方法。该方法应该看起来像这样

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;
}

但是我注意到这个特定方法(在这个项目中)并不存在postharp代码,而是在我使用postharp方面的其他地方。

出于某种原因,即使我的项目属性上的enable postharp按钮也没有工作,所以我不得不手动编辑我的csproj文件。

如果有一些方法可以在编译时检测到postharp没有正确加载,那就太好了。