3

我正在使用一个 C# API,它具有相当复杂的虚拟方法调用顺序,可以在类型层次结构的各个级别中被覆盖。我希望能够记录这些方法的执行顺序,并且我想知道是否有一种方法可以做到这一点,而不必用 Trace 写入类。鉴于这些类中的每一个都有超过 2k 的 LOC,手工完成将是一项非常艰巨的任务!

让我尝试给出一个常见方法流程的快速示例:

public class Base
{
    protected void Init()
    {
        this.BeginInitInternal();
        this.OnInit();
        this.AfterInitInternal();
    }

    protected virtual void AfterInitInternal() { }
    protected virtual void OnInit() { }
    protected virtual void BeginInitInternal() { }
}

public class Derived : Base
{
    protected sealed override void BeginInitInternal()
    {
        // Logic here
        this.BeginInit();
    }

    protected sealed override void AfterInitInternal()
    {
        // Logic here
        this.AfterInit();
    }

    protected virtual void BeginInit() { }
    protected virtual void AfterInit() { }
}

public class Concrete : Derived
{
    protected override void BeginInit() { /* Logic here */ }
    protected override void OnInit() { /* Logic here */ }
    protected override void AfterInit() { /* Logic here */ }
}

Concrete实现是由 API 的使用者创建的,我希望能够告知他/她所有这些调用的顺序(理想情况下也是上下文,但这超出了问题的范围。

我不一定需要 UML 序列图,但这是我找到的与我正在寻找的最接近的模拟。

理想情况下,我希望它告诉工具查看Base.Init()on的实现Derived并发出如下内容:

  1. Derived.BeginInit()
  2. Base.OnInit()
  3. Derived.AfterInit()

我已经尝试过 VS 序列图生成器,但我似乎无法告诉它使用Concrete,而是从Base.Init(). 我也尝试过使用 VS Code Map,但它阻碍了解决方案的复杂性,并且通常会出错。最后,我尝试使用 NDepend,它很接近 - 它可以告诉我所有的调用,但不能告诉我它们的顺序。

还有什么我可以尝试的,还是我应该开始Trace.WriteLines到处粘贴?

4

2 回答 2

1

哦。这是使用 Roslyn 的好案例。

如果您想从源代码中提取自定义信息,这取决于该源代码,而无需使源代码适应您的读者;我会说这是使用 Roslyn 的有力案例。

http://msdn.microsoft.com/en-us/vstudio/roslyn.aspx

于 2013-01-20T19:56:37.903 回答
0

您可以考虑拦截对每个方法的调用,并且可以执行任何开箱即用的操作,例如日志记录、创建文档等。

你可以在这里看到我们如何拦截方法的调用。

http://dotnetdlr.com/2011/05/06/intercept-calls-to-objects-in-c/

于 2013-01-22T04:13:57.650 回答