获取方法中的参数名称(并用作词典键?)

时间:2012-11-06 12:56:53

标签: c# reflection

我正在编写一个集成到现有软件中的审计日志系统,数据库结构包含一个字段,用于记录有关正在记录的操作的详细信息。不一定要花哨;它不需要太多,并且在大多数情况下,开发人员会读取它以找出调用哪种方法以及使用什么参数这样的东西。这意味着虽然它应该是人类可读的,但它不需要被任何东西解析。所以,不是有很多重载,或使用可怕的开关案例字符串替换,我想一个很好的方法来编写详细信息blob将是一个日志调用,以获取被记录的操作所需的参数的名称,以及值传递给他们的。我已经做了一些研究,并在反射方法中发现了一些有希望的东西,但我还没有找到任何可以解释清楚如何去做的事情。

这是对我所追求的事情的粗略嘲弄:

Dictionary<string,string> parameters = new Dictionary<string,string>();
foreach (Parameter p in MethodCall)
{
    parameters.Add(p.Name, p.Value.ToString());
}

LogEvent(EventType.Something, userID = thisUser, details = parameters);

我知道它可能比实际中更复杂,但它给你一般的想法。在我的LogEvent方法中,有一些东西要添加时间戳,为用户端日志查看器构建描述性句子(比我们向管理员和开发人员展示的技术细节要少,以免暴露我们的程序/数据库结构)和 - 理论上 - 构建参数详情字典中的某种blob(可能是JSON或类似的)。

4 个答案:

答案 0 :(得分:1)

相关的是:Obtain parameter values from a stack frame in .NET?,它有一些有用的答案。

您想记录方法名称和参数列表。方法名称使用StackFrame很容易,但我认为你不能使用简单的反射来获取参数值。

答案 1 :(得分:1)

如果您的日志记录方法采用表达式参数,则可以通过以下代码获取参数名称和值:

static void LogSomething(Expression<Action> expression)
{
    var methodCallExpression = ((MethodCallExpression) expression.Body);
    var parameterNames = methodCallExpression.Method.GetParameters().Select(p => p.Name);
    var values = methodCallExpression.Arguments.Select(a => a.Value);
}

答案 2 :(得分:1)

我会使用拦截器(Castle.DynamicProxy),如下例所示:

  internal class Program
  {
    private static void Main(string[] args)
    {

      var interceptor = new Interceptor();
      var businessObjectClass = new ProxyGenerator().CreateInterfaceProxyWithoutTarget<IBusinessObjectClass>(interceptor);

      businessObjectClass.Method3("what",123);

      Console.ReadLine();
    }
  }

  public class Interceptor : IInterceptor
  {
    #region IInterceptor Members

    public void Intercept(IInvocation invocation)
    {
      Console.WriteLine(string.Format("Intercepted call to: " + invocation.Method.Name));
      foreach (var argument in invocation.Arguments)
      {
        Console.WriteLine(string.Format("\t Param: " + argument.ToString()));
      }
      invocation.Proceed();
    }

    #endregion
  }

  public interface IBusinessObjectClass
  {
    void Method3(string stringValue, int intValue);
  }

  public class BusinessObjectClass : IBusinessObjectClass
  {

     public void Method3(string stringValue, int intValue)
    {
      return;
     }

  }

DynamicProxy

答案 3 :(得分:0)

为什么不试试PostSharp?它旨在解决像你这样的问题。在示例中,您将找到打印参数值的logging方面。结合XML配置,将允许管理员/用户随意启用日志记录/跟踪。