【问题标题】:Adding code to the beginning / end of methods in runtime dynamically在运行时动态地将代码添加到方法的开头/结尾
【发布时间】:2011-01-28 13:05:04
【问题描述】:

我知道检测是一种将跟踪代码动态添加到方法中以启用跟踪和调试的技术。

我想知道这是否只是一个“跟踪”选项,硬编码到 CLR 中以仅添加跟踪代码,还是可以向方法中添加任何代码?

例如,我想在某个类中的每个方法调用的开头检查一个条件(比如权限)。我可以通过在执行时将动态代码添加到方法的开头来做到这一点吗?

我不确定这个跟踪“仪器”是如何工作的,但我想知道这是否也可以用于其他目标。

【问题讨论】:

    标签: c# .net dynamic clr instrumentation


    【解决方案1】:

    基本上你应该做的是编写一个 CLR 分析器并在 c++ 中使用profiler API
    您需要实现 ICorProfilerCallback 接口。
    您正在寻找的是 JITCompilationStarted 回调。每次调用托管方法时以及在 jit 编译器将 IL 编译为机器代码之前都会调用此方法。 运行时的任何代码插入工作都应在 JITCompilationStarted 中完成。
    可以看一下开源覆盖工具part cover作为例子怎么做。

    【讨论】:

      【解决方案2】:

      您指的是面向方面的编程 (AOP)。

      看看PostSharp

      还有:Open Source Aspect-Oriented Frameworks in C#

      【讨论】:

      • 我不是指 AOP,但我想为 AOP 使用运行时工具。我知道一些很好的 AOP 框架,并且我自己编写了一个(将很快作为开源发布),我想知道是否可以使用与运行时检测相同的东西来拦截调用。 PostSharp 与我的想法最接近,但它在构建时运行。是否有运行时版本(实际上将代码添加到相同的方法中,类似于 PostSharp)?
      【解决方案3】:

      正如其他人所回答的那样,此类跨领域问题通常通过面向方面的编程 (AOP)来解决。

      执行 AOP 的一种方法是使用 PostSharp 等工具进行代码检测,但另一种不需要额外工具的方法是利用 依赖注入 (DI) 和 Decorator 设计模式。

      假设您的代码使用 IFoo 接口:

      public interface IFoo
      {
          string GetStuff(string request);
      }
      

      您可能对 IFoo 有一个具体的实现 MyFoo,但您也可以编写一个或多个处理不同方面的装饰器:

      public class AdministratorGuardingFoo : IFoo
      {
          private readonly IFoo foo;
      
          public AdministratorGuardingFoo(IFoo foo)
          {
              if (foo == null)
              {
                  throw new ArgumentNullException("foo");
              }
      
              this.foo = foo;
          }
      
          public string GetStuff(string request)
          {
              new PrincipalPermission(null, "Administrator").Demand();
      
              return this.foo.GetStuff(request);            
          }
      }
      

      您现在可以(拥有您的 DI 容器)将 MyFoo 包装在 AdministratorGuardingFoo 中。所有消费IFoo 的消费者都不会注意到差异。

      【讨论】:

        【解决方案4】:

        我知道PostSharp 允许您通过属性向现有方法添加“方面”,以便您可以在方法中添加进入/退出跟踪

        【讨论】:

        • 请看我对米奇小麦的评论。
        【解决方案5】:

        【讨论】:

        • 我认为基于消息的方法适用于远程调用,而不是本地调用。我说的对吗?
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-07-26
        • 2015-07-15
        • 2011-10-29
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多