【问题标题】:C# add Code to an Method at Runtime or with Mono.CecilC# 在运行时或使用 Mono.Cecil 将代码添加到方法
【发布时间】:2015-07-15 06:19:40
【问题描述】:

对于我的 Logging Lib,我计划开发一些功能。第一个将记录被调用的方法及其参数。例如

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

记录器现在应该记录:类 xy 参数值 = 15 中的方法 DoSomething 中的错误。 使用反射和 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 的方法。但是,如果我有一个返回某些东西的方法。我想我会遇到问题,因为我添加了代码并因此操作了堆栈。据我所知,返回值存储在 statck 中。

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

【问题讨论】:

  • PostSharp 怎么样? postsharp.net
  • 如果唯一缺少的东西是参数值,为什么不将它传递给您的记录器? void Logger.Error(Exception ex, params object[] methodParams); 对我来说似乎更简单。
  • @IronSlug 你是对的。这要简单得多,但我知道如果我在公司中使用这个库,超过一半的开发人员不会记录该参数。所以我尝试创建一个自动执行此操作的库。
  • @Alex 好吧,如果您的公司政策允许,我想您最好的选择是 Aspect Oriented Programming

标签: c# mono mono.cecil


【解决方案1】:

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

您可以查看以下文章:

Working with the C# 2.0 Command Line Compiler

Compiling C# Code at Runtime

Dynamic Load .NET Assembly

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-01-28
    • 2012-05-20
    • 1970-01-01
    • 1970-01-01
    • 2011-08-02
    • 1970-01-01
    • 2023-02-24
    • 1970-01-01
    相关资源
    最近更新 更多