在运行时动态地向方法的开头/结尾添加代码

9
我知道仪表化是一种动态添加跟踪代码到方法中以启用跟踪和调试的技术。
我想知道这是否只是一个“跟踪”选项,硬编码到CLR中只添加跟踪代码,或者是否有能力向方法中添加任何代码?
例如,我想在某个类的每个方法调用的开头检查条件(比如权限)。我能否通过在执行时间内向方法开头添加动态代码来实现此目的?
我不确定这个跟踪“仪表化”是如何工作的,但我想知道它是否可用于其他目的。
5个回答

4
基本上,您需要编写一个CLR分析器并在C++中使用分析器API。 您需要实现ICorProfilerCallback接口。 您要查找的是JITCompilationStarted回调。每次调用托管方法并在jit编译器将IL编译为机器代码之前,都会调用此方法。任何运行时的代码插入工作都应该在JITCompilationStarted中完成。您可以参考开源覆盖率工具part cover来进行操作。

3

我不是在指AOP,但我想使用AOP的运行时仪表化。我知道一些好的AOP框架,而且我自己写了一个(很快会发布为开源),我想知道是否可以将相同的东西用作运行时仪表化以拦截调用。PostSharp是我所想的最接近的东西,但它在构建时操作。是否有运行时版本(实际上向同一方法添加代码,类似于PostSharp)? - Iravanchi

2
如其他人已经回答的一样,这些横切关注点通常会使用面向切面编程(AOP)来解决。
用PostSharp等工具进行代码插装是实现AOP的一种方法,但另一种不需要额外工具的选择是利用依赖注入(DI)和装饰者设计模式。
想象你的代码使用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 的消费者都不会注意到任何差异。

0

我知道PostSharp允许你通过属性添加“方面”到现有的方法中,因此你可以在方法上添加进入/退出跟踪


请看一下我对Mitch Wheat的评论。 - Iravanchi

0

我认为基于消息的方法适用于远程调用,而不是本地调用。我说得对吗? - Iravanchi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接