如何拦截C#中的方法调用?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (16)

对于一个给定的类我想跟踪功能,即我想记录每个方法调用(方法签名和实际参数值)和每个方法退出(只是方法签名)。

我如何完成这个假设:

  • 我不想为C#使用任何第三方AOP库,
  • 我不想将重复的代码添加到所有我想跟踪的方法中,
  • 我不想更改该类的公共API - 该类的用户应该能够以完全相同的方式调用所有方法。

为了让问题更具体,我们假设有三个类:

 public class Caller 
 {
     public static void Call() 
     {
         Traced traced = new Traced();
         traced.Method1();
         traced.Method2(); 
     }
 }

 public class Traced 
 {
     public void Method1(String name, Int32 value) { }

     public void Method2(Object object) { }
 }

 public class Logger
 {
     public static void LogStart(MethodInfo method, Object[] parameterValues);

     public static void LogEnd(MethodInfo method);
 }

如何调用Logger.LogStart和Logger.LogEnd每次调用方法1和方法2,而无需修改Caller.Call方法,没有明确地加入调用Traced.Method1和Traced.Method2?

提问于
用户回答回答于

C#不是面向AOP的语言。它具有一些AOP功能,可以效仿其他一些功能,但使用C#编写AOP是很痛苦的。

我想方设法做到你想做的事情,我发现没有简单的方法来做到这一点。

据我了解,这是你想要做的:

[Log()]
public void Method1(String name, Int32 value);

为了做到这一点,你有两个主要选择

  1. 从MarshalByRefObject或ContextBoundObject继承类并定义从IMessageSink继承的属性。。
  2. 另一种选择是直接注入代码。在运行时,意味着你将不得不使用反射来“读”每个类,获得它的属性并注入适当的调用(对于这个问题,我认为你不能使用Reflection.Emit方法,因为我认为Reflection.Emit wouldn不允许你在已经存在的方法中插入新的代码)。在设计时,这意味着要创建CLR编译器的扩展,我真的不知道它是如何完成的。

最后的选择是使用IoC框架

用户回答回答于

最简单的方法是使用PostSharp。它会根据应用的属性在方法内注入代码。它可以让你做到你想要的。

另一种选择是使用profiling API在代码中注入代码,很硬核。

扫码关注云+社区