C# 测井方法设计

C# 测井方法设计,c#,logging,api-design,C#,Logging,Api Design,我正在用C#编写一个函数来记录系统中用户的操作并将其保存在数据库中。具体来说,我希望在调用业务逻辑的某些函数时记录它们。我想到了这样一种日志记录方法: public static LogMethod(string user, string methodName, object[] parameters, string message) void Foo(int a, SomeObject b) { Logger.LogMethod(username, "Foo", new objec

我正在用C#编写一个函数来记录系统中用户的操作并将其保存在数据库中。具体来说,我希望在调用业务逻辑的某些函数时记录它们。我想到了这样一种日志记录方法:

public static LogMethod(string user, string methodName, object[] parameters, string message)
void Foo(int a, SomeObject b)
{
     Logger.LogMethod(username, "Foo", new object[]{a,b}, "Beginning Foo");
     //etc
}
在方法内部,为每个参数调用适当的
ToString()
函数。 例如,方法Foo的调用方式如下:

public static LogMethod(string user, string methodName, object[] parameters, string message)
void Foo(int a, SomeObject b)
{
     Logger.LogMethod(username, "Foo", new object[]{a,b}, "Beginning Foo");
     //etc
}
这是记录函数调用的好方法吗?实现这一目标的最佳实践是什么?
它会影响性能吗?

是的,它会影响性能,因为您必须使用反射来获取MethodInfo,然后调用它。除此之外,它还破坏了可维护性,因为您无法重构方法名称


请看一下前面的问答,寻找替代方案:

不要将漂亮的业务逻辑与日志逻辑混为一谈,这是一个跨领域的问题。您应该使用类似方法拦截的技术来拦截要记录的方法

这是记录函数调用的好方法吗

不,坦白说,不是。您的代码现在与执行业务逻辑和日志有关。这是很难编写、测试和维护的代码

实现这一目标的最佳实践是什么

我鼓励您找到一种解决这个问题的方法,而不是到处记录代码,从而破坏您的代码。解决这个问题的标准方法是使用方法拦截或面向方面编程。有很多方法可以实现这一点(您可以使用许多框架中的一种来设置它,但我偏爱Castle Windsor)

它是否会对性能产生不良影响


只有你能回答这个问题。如果您正在记录用户正在做的事情,则不太可能。用户速度慢且愚蠢,他们使用的磁盘和数据库等东西速度慢,因此不太可能关心您是否需要额外的几毫秒来记录某些内容。我们这里不是在讨论关键循环但是只有您可以决定它是否慢得令人无法接受,并且只有您可以测量您自己的应用程序是否有日志记录,以查看它是否慢得令人无法接受。

正如其他人已经指出的,AOP框架可能是一条可行之路


如果你仍然想使用你的方法,你可以对它做一些小的改进。如果将参数放在末尾,则可以使用
params
关键字

public static LogMethod(string user, string methodName, string message,
                        params object[] parameters)
这使得调用该方法变得更加容易

void Foo(int a, SomeObject b)
{
    Logger.LogMethod(username, "Foo", "Beginning Foo", a, b);
    //etc  
}  

一切都会影响性能,但效果是否“坏”是主观的。这也完全取决于调用该方法的频率

如果重新排列参数并使用
params
关键字,则可以简化调用:

public static LogMethod(string user, string methodName, string message, params object[] parameters)
现在您的通话更简单:

Logger.LogMethod(username, "Foo", "Beginning Foo", a, b);
无需声明对象数组,编译器将为您处理此问题。看

此外,您还可以通过从堆栈中获取调用方法名来进一步简化调用:

public static LogMethod(string user, string message, params object[] parameters)
{
    string methodName = new StackFrame(1).GetMethod().Name;
    ...      
}
现在您不需要methodName参数。(在.NET4.5中,您可以使用实现相同的功能。)


通过反思,你可以走得更远;例如,您可以获取传递给调用方法的参数的名称、类的名称等。

您是否可以使用Microsoft?仅供参考-log4net内置了DB集成,可能很有用:非常感谢,起初我考虑使用Spring、Unity、,或者Castle Windsor,但是学习它们并将它们组合到我的项目中对于我当前的项目来说可能太耗时了,你的评论吸引了我去搜索更多关于AOP解决方案的信息,我最终在PostSharp停了下来,它看起来很适合我的需要。谢谢