inversionhourglass / Rougamo

Compile-time AOP component. Works with any method, whether it is async or sync, instance or static. Uses an aspectj-like pattern to match methods.
MIT License
393 stars 47 forks source link

拦截方法时,无法获取到out参数值 #53

Closed MichaelEdson closed 10 months ago

MichaelEdson commented 10 months ago

例如foo(out int buf),重写OnExit方法后,想通过MethodContext的Arguments属性获取out出来的buf值,但是该值一直为空,不知道是不是我哪里没搞对。。。

inversionhourglass commented 10 months ago

获取不到是正常的,参数只有在初始化的时候会获取一次,你在方法中对任何参数进行重新赋值都是不会再次变更Arguments的成员值的

MichaelEdson commented 10 months ago

获取不到是正常的,参数只有在初始化的时候会获取一次,你在方法中对任何参数进行重新赋值都是不会再次变更Arguments的成员值的

感谢回复,我的计划是针对一个工具类(上百个方法),使用rougamo加入自动打log和重试机制(分成两个特性处理),其中打log要求在接口调用前后,记录出入参的名称和值,目前基本调试完成,只是对于出参获取不到,有点可惜。 我一开始用的是PostSharp,它是可以拿到出参的,包括out和ref,记录值经历接口后的变化。只是PostSharp无法获取类的构造参数(我涉及这个工具的多实例,要获取构造参数的id用于区分不同实例的log记录),所以PostSharp放弃掉了,rougamo是可以办到的。 Rougamo获取出参的功能是否有可能更新?谢谢!

inversionhourglass commented 10 months ago

可以支持,预计下个版本里增加,不过时间上不能确定

MichaelEdson commented 10 months ago

可以支持,预计下个版本里增加,不过时间上不能确定

好的,您按您计划安排就好。 再次感谢您的工作,这个框架非常友好和易用!

inversionhourglass commented 10 months ago

感谢支持

inversionhourglass commented 10 months ago

2.1.1版本新增了更新参数值的功能,这个功能实现可以获取到out参数值。

更新参数值的完整功能是执行OnExceptionOnSuccessOnExit前会将当前参数值更新到MethodContext.Arguments中,现在在方法中对参数进行重新赋值后,在OnExceptionOnSuccessOnExit中能够获取到最新的参数值。可以通过修改MoAttribute.Features禁用该功能,比如下面的代码将启用除更新参数值外的所有功能:

public class NonFreshArgsAttribute : MoAttribute
{
    public override Feature Features => (Feature.All ^ Feature.FreshArgs) & Feature.All;
}

需要注意的是,之前的版本中在OnEntry中获取out参数值时固定获取到的事null,现在获取到的是参数类型的默认值,也就是default(T)。还有就是在out参数在初始化之前方法抛出了异常,在OnException中获取out参数值也是参数类型的默认值。

// 比如下面的例子中,当x传入1时就会直接抛出异常,此时y还没有赋值,但是在OnExecption中获取y的值会取到0
void Test(int x, out int y)
{
  if (x % 7 == 3)
  {
    y = x * 21;
  }
  else
  {
    throw new ArgumentException();
  }
}
MichaelEdson commented 10 months ago

已确认2.1.1版本可以获取Out参数的实时值,感谢!