C# 在运行时或使用 Mono.Cecil 向方法添加代码

C# add Code to an Method at Runtime or with Mono.Cecil

我计划为我的日志库开发一些功能。第一个将记录调用的方法及其参数。例如

public void DoSomething(int value) 
{
    try
    {
        // Exception is thrown
    }
    catch(Exception ex)
    {
        this._logger.Error(ex);
    }
}

Logger 现在应该记录:class xy 参数值 = 15 中的方法 DoSomething 出错。 使用 Reflection 和 StackFrame 是不可能的,我可以获得方法名称和参数名称,但不能获取参数值。 我现在的想法是在运行时或编译时之后将代码注入到这个方法中。 我用 Mono.Cecil 尝试过,所以我将代码注入到该方法中,该方法将参数的名称及其值传递给我的记录器。这是有效的。

第二个想法是在方法中添加秒表:

[AnalyzePerformanceOfMethod]
public int DoSomething(int value) 
{
    Stopwatch watch = new Stopwatch();
    watch.Start();
    try
    {
        // code
    }
    catch(Exception ex)
    {
    }
    watch.Stop();
    _logger.Write("Method took: " + watch.Elapsed.Seconds);
    return 10;
}

我的想法也是用 Mono.Cecil 添加此代码。 (只有在属性定义在方法上方时才应添加代码)。 这适用于类型为 void 的方法。但是如果我有一个 Returns 东西的方法。我想我会遇到问题,因为我添加了代码并因此操纵了堆栈。据我所知,return 值存储在 statck 中。

还有别的路可以走吗? Cecil 仅适用于未加载的程序集。有没有办法在运行时将此代码添加到定义了此属性的方法中? 如果没有其他办法,如何使用 cecil 在方法或函数的末尾添加代码?

我认为您应该尝试在运行时加载基于小界面的插件的方法。然后,您可以根据需要加载任意数量的实现,甚至可以即时生成新的 C# 代码(实现)。在运行中,您可以使用反射生成代码,甚至可以将纯文本写入文件,然后使用 cs.exe.

进行编译

您可以查看以下文章:

Working with the C# 2.0 Command Line Compiler

Compiling C# Code at Runtime

Dynamic Load .NET Assembly